在Stream reduce方法中,对于sum,标识总是0,对于乘法,1是1吗? [英] In Stream reduce method, must the identity always be 0 for sum and 1 for multiplication?

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

问题描述

我继续学习java 8。

I proceed java 8 learning.

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

I have found interesting behaviour:

让我们看看代码示例:

lets see code sample:

// 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

对于序列流,此代码始终返回73(72 + 1),但对于并行,它始终返回76(72 + 4 * 1)。 4 - 流元素计数。

12+32+10+18 = 72
For sequental stream this code returns 73(72 + 1) always but for parallel it returns 76(72 + 4*1) always. 4 - stream elements count.

当我看到这个结果时,我认为并行流和序列流返回不同的结果是很奇怪的。

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

我在某处破坏了合约吗?

Am I broke contract somewhere ?

对我来说73是预期的结果但是76 - 不是。

for me 73 is expected result but 76 - not.

推荐答案

身份值是一个值,这样 x op identity = x 。这是一个并非Java Stream 所独有的概念,请参阅 on维基百科

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) - > {Set< X> s = new HashSet<>(a); s.addAll(b); return s;})

  • reduce(Double.POSITIVE_INFINITY,Math :: min)

  • reduce(Double.NEGATIVE_INFINITY,Math :: max)

  • reduce("", String::concat)
  • reduce(true, (a,b) -> a&&b)
  • reduce(false, (a,b) -> a||b)
  • reduce(Collections.emptySet(), (a,b)->{ Set<X> s=new HashSet<>(a); s.addAll(b); return s; })
  • reduce(Double.POSITIVE_INFINITY, Math::min)
  • reduce(Double.NEGATIVE_INFINITY, Math::max)

应该清楚表达式 x + y == x 对于任意 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方法中,对于sum,标识总是0,对于乘法,1是1吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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