简体   繁体   English

它的工作原理:BigDecimal Sum with Reduce和BigDecimal :: add

[英]Why it works: BigDecimal Sum with Reduce and BigDecimal::add

I can understand why Total1 is calculated, but as Total2 is calculated I have no idea! 我可以理解为什么计算Total1,但是当计算Total2时我不知道! How can a BigDecimal::add be used in a BiFunction ? 如何在BiFunction中使用BigDecimal :: add Signatures are not the same !!! 签名不一样!!!

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);
    }
}

Its used as a BinaryOperator<T> in your current context. 它在您当前的上下文中用作BinaryOperator<T>

Its equivalent lambda representation: 它的等效lambda表示:

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

and anonymous class representation: 和匿名类表示:

new BinaryOperator<BigDecimal>() {
    @Override
    public BigDecimal apply(BigDecimal bigDecimal, BigDecimal augend) {
        return bigDecimal.add(augend);
    }
}

where BinaryOperator<T> extends BiFunction<T,T,T> , meaning its a specialization of BiFunction for the case where the operands and the result are all of the same type. 其中BinaryOperator<T> extends BiFunction<T,T,T> ,这意味着它BiFunction适用于操作数和结果都是相同类型的情况。

Added to that, your code is actually using one of the overloaded implementations of reduce method ie Stream.reduce(T identity, BinaryOperator<T> accumulator) . 除此之外,您的代码实际上使用了reduce方法的重载实现之一,即Stream.reduce(T identity, BinaryOperator<T> accumulator)


How can a BigDecimal::add be used in a BiFunction 如何在BiFunction中使用BigDecimal :: add

Just a step further and only for explanation , there is also an overloaded implementation that uses combiner as in Stream.reduce​(U identity, BiFunction<U,​? super T,​U> accumulator, BinaryOperator<U> combiner) which would look like : 更进一步, 仅用于解释 ,还有一个重载实现,使用combinerStream.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

Given BigDecimal::add is being used as a BiFunction<BigDecimal, BigDecimal, BigDecimal> , the compiler will look for one of two eligible signatures. 给定BigDecimal::add用作BiFunction<BigDecimal, BigDecimal, BigDecimal> ,编译器将查找两个符合条件的签名之一。

The first possible signature, as you have picked up on, would be a two-argument static method. 正如您所了解的那样,第一个可能的签名将是一个双参数静态方法。 The relevant lambda would be (a, b) -> BigDecimal.add(a, b) . 相关的lambda将是(a, b) -> BigDecimal.add(a, b) Of course, you are correct to recognise that this doesn't exist. 当然,你是正确的认识到这不存在。

The second possible signature would be a one-argument instance method. 第二种可能的签名是单参数实例方法。 The equivalent lambda here would be (a, b) -> a.add(b) . 这里的等价lambda是(a, b) -> a.add(b) As this one exists and the other does not, this is how the compiler would interpret it. 由于这个存在而另一个不存在,这就是编译器解释它的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM