我想创建一个lambda数组。问题是lambda可能彼此不同。例如:
if (caller.name() == classStr(MyCallerClass) )
{
// MyCallerClass.myParmMethod(parameter);
}
现在,我如何声明一个既可以包含I0又可以包含I1的列表?
private interface I0 {
int interface0(int a, int b);
}
private interface I1 {
int interface1(double d);
}
显然List<Object> test = Arrays.asList(
(int a, int b) -> a + b,
(double d) -> d * 2
);
不起作用。
答案 0 :(得分:17)
您必须首先将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>
中是什么意思。如果不将它们转换回各个功能接口类型,则无法使用它们。
答案 1 :(得分:11)
您可以投射到相应的界面,如:
List<Object> test = Arrays.asList(
(I0) (int a, int b) -> a + b,
(I1) (double d) -> (int) (d * 2)
);
尽管这个更短,但我也会考虑Eran's answer它可能更容易理解(如果有更多功能)。而且我也看不到这种结构的用例...
它变得更短(不一定更好):
List<Object> test = Arrays.asList(
(I0) (a, b) -> a + b,
(I1) d -> (int) (d * 2)
);
答案 2 :(得分: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]));
}
}
我觉得你的解决方案最终没有任何一个复杂。只是想帮助你指明正确的方向。
答案 3 :(得分:0)
你可以让你的界面使用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
);
}
}