Java: Как правильно манипулировать массивом BigDecimal с помощью функционального программирования? - PullRequest
0 голосов
/ 05 декабря 2018

Итак, как получить результат этого кода с помощью функционального программирования:

public static final List<BigDecimal> numbers = Arrays.asList(
    new BigDecimal("15"), new BigDecimal("10"), new BigDecimal("17"),
    new BigDecimal("30"), new BigDecimal("18"), new BigDecimal("23"),
    new BigDecimal("5"), new BigDecimal("12") );

BigDecimal totalOfReducedNumbers = BigDecimal.ZERO;
   for(BigDecimal number : numbers) {
       if(number.compareTo(BigDecimal.valueOf(20)) > 0) 
           totalOfReducedNumbers = 
         totalOfReducedNumbers.add(number.multiply(BigDecimal.valueOf(0.9)));
   }
System.out.println("Total of reduced numbers: " + totalOfReducedNumbers);

Что выбрасывает " Всего сокращенных чисел: 47,7 "

Как получить тот же результат, используя инструменты функционального программирования , такие как map (), redu () и т. Д.

Ответы [ 2 ]

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

Реализация цикла for является типичным шаблоном "Reduce" (также называемым в некоторых других языках шаблоном "fold", "Aggregate")

Вы ищете filter -> reduce method:

BigDecimal reduce = 
         numbers.stream()
                .filter(n -> n.compareTo(BigDecimal.valueOf(20)) > 0)
                .reduce(BigDecimal.ZERO, 
                       (a, b) -> a.add(b.multiply(BigDecimal.valueOf(0.9))));

Вы можете дополнительно минимизировать количество объектов, созданных путем кэширования BigDecimal.valueOf(20) и BigDecimal.valueOf(0.9), как показано в ответе @ Elliot, т. е.

BigDecimal TWENTY = BigDecimal.valueOf(20);
BigDecimal POINT9 = BigDecimal.valueOf(0.9);
BigDecimal reduce = 
             numbers.stream()
                    .filter(n -> n.compareTo(TWENTY) > 0)
                    .reduce(BigDecimal.ZERO, 
                           (a, b) -> a.add(b.multiply(POINT9)));
0 голосов
/ 05 декабря 2018

Выполнив те же самые операции, сначала отфильтруйте значения (вам нужны только значения больше 20).Затем умножьте эти значения на 0.9 и, наконец, уменьшите условия, выполнив сложение.Например,

BigDecimal TWENTY = BigDecimal.valueOf(20);
BigDecimal POINT9 = BigDecimal.valueOf(0.9);
System.out.println("Total of reduced numbers: " + numbers.stream()
        .filter(x -> x.compareTo(TWENTY) > 0)
        .map(x -> x.multiply(POINT9)).reduce((a, b) -> a.add(b)).get());

Выходы (в соответствии с запросом)

Total of reduced numbers: 47.7

И, как предлагается в комментариях, мы можем еще больше улучшить это с помощью ссылки на метод, и использование orElse будет безопаснеечем сырой get().Мол,

System.out.println("Total of reduced numbers: " + numbers.stream() 
        .filter(x -> x.compareTo(TWENTY) > 0) 
        .map(x -> x.multiply(POINT9)) 
        .reduce(BigDecimal::add) 
        .orElse(BigDecimal.ZERO));
...