I can understand why Total1 is calculated, but as Total2 is calculated I have no idea! How can a BigDecimal::add be used in a BiFunction? Signatures are not the same !!!
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);
}
}
Its used as a BinaryOperator<T>
in your current context.
Its equivalent lambda representation:
(bigDecimal, augend) -> bigDecimal.add(augend) // same as in your previous line of code
and anonymous class representation:
new BinaryOperator<BigDecimal>() {
@Override
public BigDecimal apply(BigDecimal bigDecimal, BigDecimal augend) {
return bigDecimal.add(augend);
}
}
where BinaryOperator<T> extends BiFunction<T,T,T>
, meaning its a specialization of BiFunction
for the case where the operands and the result are all of the same type.
Added to that, your code is actually using one of the overloaded implementations of reduce
method i.e. Stream.reduce(T identity, BinaryOperator<T> accumulator)
.
How can a BigDecimal::add be used in a BiFunction
Just a step further and only for explanation, there is also an overloaded implementation that uses combiner
as in Stream.reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
which would look like :
BigDecimal total = list.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add, BigDecimal::add);
// ^^ ^^
// BiFunction here BinaryOperator here
Given BigDecimal::add
is being used as a BiFunction<BigDecimal, BigDecimal, BigDecimal>
, the compiler will look for one of two eligible signatures.
The first possible signature, as you have picked up on, would be a two-argument static method. The relevant lambda would be (a, b) -> BigDecimal.add(a, b)
. Of course, you are correct to recognise that this doesn't exist.
The second possible signature would be a one-argument instance method. The equivalent lambda here would be (a, b) -> a.add(b)
. As this one exists and the other does not, this is how the compiler would interpret it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With