Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does BigDecimal#min method qualify as a BinaryOperator?

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.

like image 432
Jeffrey Sze Avatar asked Mar 31 '17 08:03

Jeffrey Sze


2 Answers

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);
like image 114
Eugene Avatar answered Oct 19 '22 19:10

Eugene


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.

like image 35
glee8e Avatar answered Oct 19 '22 21:10

glee8e