Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda: Declare Generic Type Inline

My Goal

I want to write a generic timing function (I removed the actual timing code for this question as it doesn't really matter).

I have a function with unknown input and output. I want to run this function a couple of times in a loop and pass it the loop variable.

To do this, I defined an interface that can transform the loop variable to the type that the function needs.

My Code

interface Function<R,T> {
    R run(T input);
}

interface InputGenerater<T> {
    T fromLoop(int i);
}

public static void time(Function func, InputGenerater in) {
    for (int i = 0; i < 10; i++) {
        func.run(in.fromLoop(i));
    }
}

public static void main(String[] args) {
    // example: my function expects a string, so we transform the loop variable to a string:
    InputGenerater<String> intToString = (int i) -> String.valueOf(i) + "test";

    Function<String, String> funcToTest = (String s) -> s + s;
    time(funcToTest, intToString);

    Function<String, String> funcToTest2 = (String s) -> s + s + s;
    time(funcToTest2, intToString);

    // I can not only test string->string functions, but anything I want:
    InputGenerater<Integer> intToInt = (int i) -> i;
    Function<Integer, Integer> funcToTestInt = (Integer i) -> i + i;
    time(funcToTestInt, intToInt);
}

My Problem

The above code works fine, but I would prefer not to have the funcToTest, etc variables as they are only used on one line.

So I would like the main method to look like this:

    InputGenerater<String> intToString = (int i) -> String.valueOf(i) + "test";

    time((String s) -> s + s, intToString);
    time((String s) -> s + s + s, intToString);

    InputGenerater<Integer> intToInt = (int i) -> i;
    time((Integer i) -> i + i, intToInt);

But it doesn't work: Incompatible types in lambda expression.

Is there a way to declare the parameter type inline, instead of declaring it by declaring the Function<String, String> variable?

like image 294
tim Avatar asked Apr 09 '26 09:04

tim


1 Answers

You are using raw types in your time function: you should use generics and your code will compile as expected:

public static <R, T> void time(Function<R, T> func, InputGenerater<T> in)

Also note that the Function interface that you have defined already exists in the JDK (its method is apply instead of run) and the InputGenerator also exists and is called IntFunction.

So it would make sense to get rid of those interfaces and use those provided by the JDK instead.

So the final version could look like:

public static <R, T> void time(Function<R, T> func, IntFunction<T> in) { ... }

and you main method:

time(s -> s + s, i -> i + "test"); //s is a string
time(i -> i + i, i -> i); //i is an int
like image 96
assylias Avatar answered Apr 11 '26 23:04

assylias



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!