Java:如何使用函数式编程正确操作BigDecimal数组?

jus*_*uck 6 java functional-programming bigdecimal java-8

那么,如何使用函数式编程获得此代码的结果:

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);
Run Code Online (Sandbox Code Playgroud)

其中抛出" 总数减少:47.7 "

如何使用 map(),reduce()等函数式编程工具获得相同的结果

Ell*_*sch 10

通过执行相同的操作,首先过滤值(您只需要大于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());
Run Code Online (Sandbox Code Playgroud)

产出(按要求)

Total of reduced numbers: 47.7
Run Code Online (Sandbox Code Playgroud)

并且,正如评论中所建议的那样,我们可以通过方法参考进一步改进,使用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));
Run Code Online (Sandbox Code Playgroud)

  • 你可以将`(a,b) - > a.add(b)`更改为方法引用`reduce(BigDecimal :: add)`,如果它使事情更具可读性......我还要添加`.orElse( BigDecimal.ZERO)`而不是调用`get()` (4认同)
  • @Aomine方法引用相对于lambda具有另一个优势:lambda编译为附加的匿名类,而方法引用则不然. (2认同)

Ous*_* D. 8

for循环实现是典型的"reduce"模式(在其他一些语言中也称为"fold","Aggregate"模式)

你在寻找filter- > reduce方法:

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))));
Run Code Online (Sandbox Code Playgroud)

您可以进一步减少通过缓存对象池莉构建的数量BigDecimal.valueOf(20),并BigDecimal.valueOf(0.9)如图@艾略特的答案,即:

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)));
Run Code Online (Sandbox Code Playgroud)