在Stream reduce方法中,求和的标识必须始终为0,乘法的标识必须始终为1吗? [英] In Stream reduce method, must the identity always be 0 for sum and 1 for multiplication?

查看:21
本文介绍了在Stream reduce方法中,求和的标识必须始终为0,乘法的标识必须始终为1吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继续学习 Java 8.

I proceed with java 8 learning.

我发现了一个有趣的行为:

I have found an interesting behavior:

让我们看看代码示例:

// identity value and accumulator and combiner
Integer summaryAge = Person.getPersons().stream()
        //.parallel()  //will return surprising result
        .reduce(1,
                (intermediateResult, p) -> intermediateResult + p.age,
                (ir1, ir2) -> ir1 + ir2);
System.out.println(summaryAge);

和模型类:

public class Person {

    String name;

    Integer age;
    ///...

    public static Collection<Person> getPersons() {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("Vasya", 12));
        persons.add(new Person("Petya", 32));
        persons.add(new Person("Serj", 10));
        persons.add(new Person("Onotole", 18));
        return persons;
   }
}

12+32+10+18 = 72.对于顺序流,此代码始终返回 7372 + 1 但对于并行,它始终返回 7672 +4*1(4 等于流元素数).

12+32+10+18 = 72. For sequential stream, this code always returns 73 which is 72 + 1 but for parallel, it always returns 76 which is 72 + 4*1 (4 is equal to stream elements count).

看到这个结果我觉得很奇怪并行流和顺序流返回不同的结果.

When I saw this result I thought that it is strange that parallel stream and sequential streams return different results.

我是否在某处违反了合同?

Am I broke contract somewhere?

对我来说,73 是预期的结果,但 76 不是.

for me, 73 is expected result but 76 is not.

推荐答案

identity 值是一个值,使得 x op identity = x.这是一个并非 Java Stream 独有的概念,例如参见维基百科.

The identity value is a value, such that x op identity = x. This is a concept which is not unique to Java Streams, see for example on Wikipedia.

列出了一些标识元素的例子,其中一些可以直接用Java代码表示,例如

It lists some examples of identity elements, some of them can be directly expressed in Java code, e.g.

  • reduce("", String::concat)
  • reduce(true, (a,b) -> a&&b)
  • reduce(false, (a,b) -> a||b)
  • reduce(Collections.emptySet(),(a,b)->{设置s=新的哈希集(a);s.addAll(b);返回 s;})
  • reduce(Double.POSITIVE_INFINITY, Math::min)
  • reduce(Double.NEGATIVE_INFINITY, Math::max)

应该清楚,对于任意x的表达式x + y == x只能在y==0时满足,因此 0 是添加的标识元素.类似地,1 是乘法的单位元素.

It should be clear that the expression x + y == x for arbitrary x can only be fulfilled when y==0, thus 0 is the identity element for the addition. Similarly, 1 is the identity element for the multiplication.

更复杂的例子是

  • 减少谓词流

  • Reducing a stream of predicates

reduce(x->true, Predicate::and)
reduce(x->false, Predicate::or)

  • 减少函数流

  • Reducing a stream of functions

    reduce(Function.identity(), Function::andThen)
    

  • 这篇关于在Stream reduce方法中,求和的标识必须始终为0,乘法的标识必须始终为1吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆