Почему это работает: BigDecimal Sum с Reduce и BigDecimal :: add - PullRequest
0 голосов
/ 31 декабря 2018

Я могу понять, почему рассчитывается 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);
    }
}

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Учитывая, что BigDecimal::add используется как BiFunction<BigDecimal, BigDecimal, BigDecimal>, компилятор будет искать одну из двух подходящих подписей.

Первая возможная подпись, как вы выбрали, будет двух-Аргумент статический метод.Соответствующая лямбда будет (a, b) -> BigDecimal.add(a, b).Конечно, вы правы, признав, что этого не существует.

Второй возможной сигнатурой будет метод экземпляра с одним аргументом.Эквивалентная лямбда здесь будет (a, b) -> a.add(b).Поскольку это существует, а другое нет, это то, как компилятор будет его интерпретировать.

0 голосов
/ 31 декабря 2018

Используется как BinaryOperator<T> в вашем текущем контексте.

Эквивалентное лямбда-представление:

(bigDecimal, augend) -> bigDecimal.add(augend) // same as in your previous line of code

и анонимный класспредставление:

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).


Как может BigDecimal ::add будет использоваться в 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
...