这是设计中java lambda的限制吗?

Tom*_*Tom 6 scala java-8

我想定义一个简单的lambda,加起来三个整数:

(int a, int b,int c)->a+b+c
Run Code Online (Sandbox Code Playgroud)

对于这个简单的情况,我有两个选择:

  1. 定义功能界面.单个抽象方法应该是int add(int a, int b,int c),方法名称和可变量名称无关紧要.

  2. 使用方法参考.我必须定义一个类/方法或使用具有签名的现有方法int add(int a, int b,int c)

在这两种情况下,对于非常简单的lambda,我必须回到OOP世界(接口,类等)

但是在scala中,定义一个函数非常简单: val add= (a:Int,b:Int,c:Int)=>a+b+c

Fed*_*ner 6

在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)

虽然我怀疑这根本不可读......

  • 甚至更短,没有拳击开销:`IntFunction <IntBinaryOperator> add = a - >(b,c) - > a + b + c;`和`int result = add.apply(1).applyAsInt(2,3 );`... (2认同)

Ale*_*nov 6

实际上,在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在类型推理方面胜出,有两种方式:

  1. FunctionN 是lambda表达式的"默认"功能接口,因此不需要指定它.

  2. 如果指定参数,则通常可以推断返回类型.

但是,在将lambdas分配给字段或变量时,这些考虑更重要,而将它们传递给方法则更少,这可能更常见.

  • 关键点是,期望某个函数作为参数的方法必须指定描述预期函数形状的参数类型.这就是功能界面的用途.另一方面,将函数指定为lambda表达式的调用者不需要指定类型. (2认同)