The Stream.reduce
method takes a BinaryOperator
as an argument. The function signature of a BinaryOperator
is (T,T) -> T
. The BigDecimal::min
method has only 1 parameter in its method signature (ie. (T) -> T
).
Why doesn't the compiler complain when I pass BigDecimal::min
to the Stream.reduce
method?
Sample code:
List<BigDecimal> bigDecimalList = new ArrayList<>();
bigDecimalList.add(BigDecimal.valueOf(1));
bigDecimalList.add(BigDecimal.valueOf(2));
bigDecimalList.add(BigDecimal.valueOf(3));
BigDecimal minResult = bigDecimalList.stream().reduce(BigDecimal::min).orElse(BigDecimal.ZERO);
Thanks.
This is actually called Reference to an instance method of an arbitrary object of a particular type.
The compiler takes the calling instance as the first argument and as such these are equivalent:
BinaryOperator<BigDecimal> b = (left, right) -> left.min(right);
BinaryOperator<BigDecimal> b2 = BigDecimal::min;
b2.apply(left, right);
Things are much funner IMO when you have something like this:
@FunctionalInterface
interface TriFunction<A, B, C, R> {
R apply(A a, B b, C c);
}
and a theoretical class:
class Test {
int x;
int y;
public Test(int x, int y) {
this.x = x;
this.y = y;
}
public Test copy(int n, int m) {
return new Test(m, n);
}
}
Then you could write something like this:
TriFunction<Test, Integer, Integer, Test> f = Test::copy;
TriFunction<Test, Integer, Integer, Test> f2 =
(test, i, j) -> test.copy(i, j);
Because BigDecimal::min
is an instance method. Javac is smart enough to turn it into a (T, T) -> T
if you use BigDecimal::min
. The first paramter passed to the resulting BinaryOperator
will be the instance and the second will be the parameter of min
(though in BinaryOperator
's case it is required that the order can be reversed). It will be (T) -> T
if you use something like new BigInteger(1)::min
.
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