[英]Declare array of lambdas in Java
我想创建一个lambda数组。 问题是lambda可能彼此不同。 例:
private interface I0 {
int interface0(int a, int b);
}
private interface I1 {
int interface1(double d);
}
现在,我如何声明一个既可以包含I0又可以包含I1的列表?
List<Object> test = Arrays.asList(
(int a, int b) -> a + b,
(double d) -> d * 2
);
显然Object
不起作用。
您必须首先将lambda表达式分配给功能接口类型的变量。
否则,编译器无法推断这些lambda表达式的类型。
I0 i0 = (int a, int b) -> a + b;
I1 i1 = (double d) -> (int) (d * 2);
List<Object> test = Arrays.asList(
i0,
i1
);
也就是说,我不确定将这些lambda表达式存储在List<Object>
。 如果不将它们转换回各个功能接口类型,则无法使用它们。
您可以转换到相应的界面,如:
List<Object> test = Arrays.asList(
(I0) (int a, int b) -> a + b,
(I1) (double d) -> (int) (d * 2)
);
尽管这个更短,但我也会考虑Eran的答案 ,它可能更容易理解(如果有更多功能)。 我也看不到这种结构的用例......
它变得更短(不一定更好):
List<Object> test = Arrays.asList(
(I0) (a, b) -> a + b,
(I1) d -> (int) (d * 2)
);
从我收集到的,你正试图做这样的事情:
public static void main(String... args){
List<Object> lambdas = Arrays.asList(
(IntBinaryOperator) (int a, int b) -> a + b,
(DoubleToIntFunction) (double d) -> (int)(d * 2)
);
for(int i=0;i<args.length;i++){
// Apply lambdas.get(i) to args[i]
}
}
不过,这个评论非常重要; 你会如何实现它?
您可以在每轮检查中检查类型:
for(int i=0;i<args.length;i++){
if(lambdas.get(i) instanceof IntBinaryOperator){
processedArgs[i] =
((IntBinaryOperator) lambdas.get(i)).applyAsInt(MAGIC_NUMBER, Integer.parseInt(args[i]));
}else{
// All your other cases (may take a while)
}
}
验证每种可能的类型是一个巨大的痛苦,如果它是位置依赖的,它只会运行一次,所以它是过度的。
我的建议取决于它是静态的(你的代码只在一个特定的参数集上运行)还是动态的(它需要在所有类型的参数上运行)。 对于静态代码,我只是在没有循环的情况下应用lambdas:
public static void main(String... args){
processedArgs = new int[args.length];
IntBinaryOperator op1 = (int a, int b) -> a + b;
DoubleToIntFunction op2 = (double d) -> (int)(d * 2);
processedArgs[0] = op1.applyAsInt(MAGIC_NUMBER, Integer.parseInt(args[0]));
processedArgs[1] = op2.applyAsInt(Double.parseDouble(args[1]));
}
对于动态解决方案,我建议切换到单个功能接口。 我会满足最高要求并在不需要的地方填写虚拟值:
public static void main(String... args){
processedArgs = new int[args.length];
List<DoubleBinaryOperator> ops = Arrays.asList(
(a, b) -> a + b,
(d, ignore) -> (d * 2)
);
for(int i=0;i<args.length;i++){
processedArgs[i] = (int)ops.get(i).applyAsDouble(Double.parseDouble(args[i]), MAGIC_NUMBER);
}
}
或者,最好是,如果你可以简化你的lambdas:
public static void main(String... args){
processedArgs = new int[args.length];
List<DoubleToIntFunction> ops = Arrays.asList(
(d) -> (int)(d + MAGIC_NUMBER),
(d) -> (int)(d * 2)
);
for(int i=0;i<args.length;i++){
processedArgs[i] = ops.get(i).applyAsInt(Double.parseDouble(args[i]));
}
}
我觉得你的解决方案最终没有任何一个复杂。 只是想帮助指出你正确的方向。
你可以让你的界面使用vararg输入:
public class NaryFunctionTest {
interface NaryFunction<R extends Number> {
R run(R... args);
}
@Test
public void test() {
NaryFunction<Integer> f1 = (Integer[] o) -> o[0] + o[1];
NaryFunction<Double> f2 = (Double[] o) -> o[0] *2;
List<NaryFunction<?>> test = Arrays.asList(
f1,
f2
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.