我想定义一个简单的lambda,加起来三个整数:
(int a, int b,int c)->a+b+c
Run Code Online (Sandbox Code Playgroud)
对于这个简单的情况,我有两个选择:
定义功能界面.单个抽象方法应该是int add(int a, int b,int c),方法名称和可变量名称无关紧要.
使用方法参考.我必须定义一个类/方法或使用具有签名的现有方法int add(int a, int b,int c)
在这两种情况下,对于非常简单的lambda,我必须回到OOP世界(接口,类等)
但是在scala中,定义一个函数非常简单:
val add= (a:Int,b:Int,c:Int)=>a+b+c
在Java中,必须将每个lambda表达式定位到特定的功能接口类型.这是设计的,在实践中它意味着功能不是语言的一等公民.
所以,是的,你必须回到OOP世界.
但是,您可以使用Function内置类型以其currified形式定义您的函数:
Function<Integer, Function<Integer, Function<Integer, Integer>>> add =
a -> b -> c -> a + b + c;
Run Code Online (Sandbox Code Playgroud)
用法:
int result = add.apply(1).apply(2).apply(3); // 6
Run Code Online (Sandbox Code Playgroud)
虽然我怀疑这根本不可读......
实际上,在Scala中定义函数与选项1完全相同,除了1)功能接口scala.Function3[A1, A2, A3, B]包含在标准Scala库中; 2)编译器假装支持Int泛型(最终被转换为盒装java.lang.Integer.
在Java中你无法做任何关于2)的事情,但1)通过使用定义的库Function3(或编写自己的)来解决这个问题.有http://www.functionaljava.org/,http://www.vavr.io/,https://mvnrepository.com/artifact/uk.org.potes.java8/java8-currying(其中只有那些接口,仅此而已).可能还有其他几个.
当然,Scala在类型推理方面胜出,有两种方式:
FunctionN 是lambda表达式的"默认"功能接口,因此不需要指定它.
如果指定参数,则通常可以推断返回类型.
但是,在将lambdas分配给字段或变量时,这些考虑更重要,而将它们传递给方法则更少,这可能更常见.