【问题标题】:Why it works: BigDecimal Sum with Reduce and BigDecimal::add为什么有效:BigDecimal Sum 与 Reduce 和 BigDecimal::add
【发布时间】:2018-12-31 03:32:54
【问题描述】:

我可以理解为什么要计算 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);
    }
}

【问题讨论】:

    标签: java lambda java-8 java-stream functional-interface


    【解决方案1】:

    它在您当前的上下文中用作 BinaryOperator&lt;T&gt;

    它的等效 lambda 表示:

    (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&lt;T&gt; extends BiFunction&lt;T,T,T&gt;,表示其BiFunction 的特化,适用于操作数和结果都属于同一类型的情况。

    此外,您的代码实际上使用了reduce 方法的重载实现之一,即Stream.reduce(T identity, BinaryOperator&lt;T&gt; accumulator)


    BigDecimal::add 如何在 BiFunction 中使用

    再进一步只是为了解释,还有一个使用combiner 的重载实现,就像Stream.reduce​(U identity, BiFunction&lt;U,​? super T,​U&gt; accumulator, BinaryOperator&lt;U&gt; combiner) 一样:

    BigDecimal total = list.stream()
                           .reduce(BigDecimal.ZERO, BigDecimal::add, BigDecimal::add);
    //                                                   ^^                ^^
    //                                              BiFunction here    BinaryOperator here
    

    【讨论】:

    • 非常好的和完整的答案!
    【解决方案2】:

    鉴于BigDecimal::add 被用作BiFunction&lt;BigDecimal, BigDecimal, BigDecimal&gt;,编译器将寻找两个符合条件的签名之一。

    正如您所了解的,第一个可能的签名是两个参数的静态方法。相关的 lambda 为 (a, b) -&gt; BigDecimal.add(a, b)。当然,你承认这不存在是正确的。

    第二种可能的签名是单参数实例方法。这里等效的 lambda 是(a, b) -&gt; a.add(b)。由于这个存在而另一个不存在,这就是编译器将如何解释它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多