Lambda:声明通用类型内联

时间:2014-09-30 10:58:29

标签: 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);
}

我的问题

上面的代码工作正常,但我不想使用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);

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

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

1 个答案:

答案 0 :(得分:5)

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

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

另请注意,您定义的Function界面already exists in the JDK(其方法为apply而不是run)且InputGenerator也存在且{ {3}}

因此,删除这些接口并使用JDK提供的接口是有意义的。

所以最终版本看起来像:

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

和你的主要方法:

time(s -> s + s, i -> i + "test"); //s is a string
time(i -> i + i, i -> i); //i is an int