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>变量来声明它?
您在时间函数中使用原始类型:您应该使用泛型,您的代码将按预期编译:
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)
| 归档时间: |
|
| 查看次数: |
995 次 |
| 最近记录: |