在Java 8中,带有2个箭头的lambda是什么意思?

我已经阅读过几个Java 8教程。

现在我遇到了以下主题: java是否支持Currying?

在这里,我看到下面的代码:

IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b; System.out.println(curriedAdd.apply(1).applyAsInt(12)); 

我明白这个例子总结了2个元素,但我不明白这个构造:

 a -> b -> a + b; 

根据expression式的左边部分,该行应该执行以下function:

 R apply(int value); 

在此之前,我只能用一个箭头认识lambda。

如果您将其表示为非简写lambda语法或pre-lambda Java匿名类语法,则会更清楚发生了什么…

原来的问题。 为什么是两个箭头? 简单的说,定义了两个函数…第一个函数是函数定义函数,第二个函数是函数的结果,也是函数的结果。 每个都需要一个->运算符来定义它。

非速记

 IntFunction<IntUnaryOperator> curriedAdd = (a) -> { return (b) -> { return a + b; }; }; 

在Java 8之前的Lambda

 IntFunction<IntUnaryOperator> curriedAdd = new IntFunction<IntUnaryOperator>() { @Override public IntUnaryOperator apply(final int value) { IntUnaryOperator op = new IntUnaryOperator() { @Override public int applyAsInt(int operand) { return operand + value; } }; return op; } }; 

一个IntFunction<R>是一个函数int -> R IntUnaryOperator是一个函数int -> int

因此,一个IntFunction<IntUnaryOperator>是一个函数,它接受一个int作为参数,并返回一个函数,它接受一个int作为参数并返回一个int

 a -> b -> a + b; ^ | | | --------- | ^ | | | The IntUnaryOperator (that takes an int, b) and return an int (the sum of a and b) | The parameter you give to the IntFunction 

也许这是更清楚,如果你使用匿名类来“分解”的lambda:

 IntFunction<IntUnaryOperator> add = new IntFunction<IntUnaryOperator>() { @Override public IntUnaryOperator apply(int a) { return new IntUnaryOperator() { @Override public int applyAsInt(int b) { return a + b; } }; } }; 

添加括号可能会使这个更清楚:

 IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b)); 

或者可能中间variables可能有帮助:

 IntFunction<IntUnaryOperator> curriedAdd = a -> { IntUnaryOperator op = b -> a + b; return op; }; 

让我们用括号重写lambdaexpression式,使之更加清晰:

 IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b)); 

所以我们正在声明一个函数,它返回一个int 。 更具体地说,返回的函数接受一个int并返回一个int (两个元素的和):这可以表示为一个IntUnaryOperator

因此, curriedAdd是一个接受int并返回一个IntUnaryOperator ,所以它可以表示为IntFunction<IntUnaryOperator>

这是两个lambdaexpression式。

 IntFunction<IntUnaryOperator> curriedAdd = a -> { //this is for the fixed value return b -> { //this is for the add operation return a + b; }; } IntUnaryOperator addTwo = curriedAdd.apply(2); System.out.println(addTwo.applyAsInt(12)); //prints 14 

如果你看看IntFunction它可能会变得更清晰: IntFunction<R>是一个FunctionalInterface 。 它表示一个函数,它接受一个int并返回一个Rtypes的值。

在这种情况下,返回typesR也是一个FunctionalInterface ,也就是一个IntUnaryOperator 。 所以第一个 (外部)函数本身返回一个函数。

在这种情况下:当应用于一个intcurriedAdd应该返回一个函数,再次接受一个int (并返回int ,因为这是IntUnaryOperator所做的)。

在函数式编程中,通常把函数的types写成param -> return_value ,你可以在这里看到。 所以curriedAdd的types是int -> int -> int (或者int -> (int -> int)如果你更喜欢的话)。

Java 8的lambda语法随之而来。 要定义这样的function,你写

 a -> b -> a + b 

这与实际的lambda演算非常相似:

 λa λb a + b 

λb a + b是采用单个参数b并返回一个值(和)的函数。 λa λb a + b是接受单个参数a并返回单个参数a另一个函数的函数。 λa λb a + b返回λb a + b并设置为参数值。