Lambda:声明通用类型内联

tim*_*tim 2 java generics lambda java-8

我的目标

我想写一个通用的计时功能(我删除了这个问题的实际时间码,因为它并不重要).

我有一个输入和输出未知的函数.我想在循环中运行这个函数几次并将循环变量传递给它.

为此,我定义了一个接口,可以将循环变量转换为函数所需的类型.

我的守则

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);
}
Run Code Online (Sandbox Code Playgroud)

我的问题

上面的代码工作正常,但我不希望有funcToTest等变量,因为它们只用在一行上.

所以我希望主要方法看起来像这样:

    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);
Run Code Online (Sandbox Code Playgroud)

但它不起作用:Incompatible types in lambda expression.

有没有办法声明参数类型内联,而不是通过声明Function<String, String>变量来声明它?

ass*_*ias 5

您在时间函数中使用原始类型:您应该使用泛型,您的代码将按预期编译:

public static <R, T> void time(Function<R, T> func, InputGenerater<T> in)
Run Code Online (Sandbox Code Playgroud)

另请注意,Function您定义的接口已经存在于JDK中(其方法apply代替run),并且InputGenerator也存在并被调用IntFunction.

因此,摆脱这些接口并使用JDK提供的接口是有意义的.

所以最终版本看起来像:

public static <R, T> void time(Function<R, T> func, IntFunction<T> in) { ... }
Run Code Online (Sandbox Code Playgroud)

而你的主要方法:

time(s -> s + s, i -> i + "test"); //s is a string
time(i -> i + i, i -> i); //i is an int
Run Code Online (Sandbox Code Playgroud)

  • @tim`time((整数i) - > i + i,(int i) - > i);`编译好.实际上`时间(我 - >我+我,我 - >我);`也编译. (2认同)