为什么有效:BigDecimal Sum with Reduce 和 BigDecimal::add
Why it works: BigDecimal Sum with Reduce and BigDecimal::add
我能理解为什么要计算Total1,但是要计算Total2我就不知道了!
BigDecimal::add 如何用在 BiFunction 中?签名不一样!!!
package br.com.jorge.java8.streams.bigdecimal;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class BigDecimalSumTest {
public static void main(String[] args) {
List<BigDecimal> list = new ArrayList<>();
list.add(new BigDecimal("1"));
list.add(new BigDecimal("2"));
BigDecimal total1 = list.stream().reduce(BigDecimal.ZERO, (t, v) -> t.add(v));
BigDecimal total2 = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("Total 1: " + total1);
System.out.println("Total 2: " + total2);
}
}
它在您当前的上下文中用作 BinaryOperator<T>
。
其等效的 lambda 表示:
(bigDecimal, augend) -> bigDecimal.add(augend) // same as in your previous line of code
和匿名class表示:
new BinaryOperator<BigDecimal>() {
@Override
public BigDecimal apply(BigDecimal bigDecimal, BigDecimal augend) {
return bigDecimal.add(augend);
}
}
其中 BinaryOperator<T> extends BiFunction<T,T,T>
,意味着它 对 BiFunction
的特化,用于操作数和结果都属于同一类型的情况。
除此之外,您的代码实际上使用了 reduce
方法的重载实现之一,即 Stream.reduce(T identity, BinaryOperator<T> accumulator)
.
How can a BigDecimal::add be used in a BiFunction
更进一步,仅用于解释,还有一个使用 combiner
的重载实现,如 Stream.reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
所示:
BigDecimal total = list.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add, BigDecimal::add);
// ^^ ^^
// BiFunction here BinaryOperator here
鉴于 BigDecimal::add
被用作 BiFunction<BigDecimal, BigDecimal, BigDecimal>
,编译器将寻找两个符合条件的签名之一。
如您所见,第一个可能的签名是双参数静态方法。相关的 lambda 将是 (a, b) -> BigDecimal.add(a, b)
。当然,你认识到这不存在是正确的。
第二种可能的签名是单参数实例方法。此处等效的 lambda 为 (a, b) -> a.add(b)
。由于这个存在而另一个不存在,因此编译器将这样解释它。
我能理解为什么要计算Total1,但是要计算Total2我就不知道了! BigDecimal::add 如何用在 BiFunction 中?签名不一样!!!
package br.com.jorge.java8.streams.bigdecimal;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class BigDecimalSumTest {
public static void main(String[] args) {
List<BigDecimal> list = new ArrayList<>();
list.add(new BigDecimal("1"));
list.add(new BigDecimal("2"));
BigDecimal total1 = list.stream().reduce(BigDecimal.ZERO, (t, v) -> t.add(v));
BigDecimal total2 = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("Total 1: " + total1);
System.out.println("Total 2: " + total2);
}
}
它在您当前的上下文中用作 BinaryOperator<T>
。
其等效的 lambda 表示:
(bigDecimal, augend) -> bigDecimal.add(augend) // same as in your previous line of code
和匿名class表示:
new BinaryOperator<BigDecimal>() {
@Override
public BigDecimal apply(BigDecimal bigDecimal, BigDecimal augend) {
return bigDecimal.add(augend);
}
}
其中 BinaryOperator<T> extends BiFunction<T,T,T>
,意味着它 对 BiFunction
的特化,用于操作数和结果都属于同一类型的情况。
除此之外,您的代码实际上使用了 reduce
方法的重载实现之一,即 Stream.reduce(T identity, BinaryOperator<T> accumulator)
.
How can a BigDecimal::add be used in a BiFunction
更进一步,仅用于解释,还有一个使用 combiner
的重载实现,如 Stream.reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
所示:
BigDecimal total = list.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add, BigDecimal::add);
// ^^ ^^
// BiFunction here BinaryOperator here
鉴于 BigDecimal::add
被用作 BiFunction<BigDecimal, BigDecimal, BigDecimal>
,编译器将寻找两个符合条件的签名之一。
如您所见,第一个可能的签名是双参数静态方法。相关的 lambda 将是 (a, b) -> BigDecimal.add(a, b)
。当然,你认识到这不存在是正确的。
第二种可能的签名是单参数实例方法。此处等效的 lambda 为 (a, b) -> a.add(b)
。由于这个存在而另一个不存在,因此编译器将这样解释它。