Java 8 使用身份合并器并行流进行Reduce
我还没有从评论中看到这个链接,但是文档非常清楚地说明了Java 8 使用身份合并器并行流进行Reduce,java-8,java-stream,reduce,Java 8,Java Stream,Reduce,我还没有从评论中看到这个链接,但是文档非常清楚地说明了identity,它甚至提供了一种简单的测试方法: 标识值必须是组合器函数的标识。这意味着对于所有u,组合器(标识,u)等于u 让我们稍微简化一下您的示例: numbers.reduce(1, (a, b) -> a + b, (x, y) -> x - y)); 即使你认为你会用zero来代替身份,那也行;文件提出了另一个论点: 此外,组合器功能必须与累加器功能兼容;对于所有u和t,必须满足以下条件: 您可以进行相同的测试
identity
,它甚至提供了一种简单的测试方法:
标识值必须是组合器函数的标识。这意味着对于所有u,组合器(标识,u)等于u
让我们稍微简化一下您的示例:
numbers.reduce(1, (a, b) -> a + b, (x, y) -> x - y));
即使你认为你会用zero
来代替身份,那也行;文件提出了另一个论点:
此外,组合器功能必须与累加器功能兼容;对于所有u和t,必须满足以下条件:
您可以进行相同的测试:
combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
您违反了
reduce
合同,因为1
不是累加器/合路器的身份。为什么它不是一个身份?请参阅此代码-(ReduceDemo3),该链接也存在一些问题,因为它违反了一些属性;请阅读文档,而不是任何人都可以设置网页。它们有很多,告诉你的不多。但你链接的那个页面是最糟糕的,只是错误得可怕。也许有帮助……或者换句话说,在reduce
中做两件完全不同的事情,比如(a,b)->a+b
和(x,y)->x-y
,都是无稽之谈。此外,(x,y)->x-y
本身已经违反了合同,因为它没有关联性。令人印象深刻的是,该网页的作者在一个例子中尝试了多少错误的东西…@Holger我只能说,能够将一些代码移植到java-8(而管理者完全不知道理解这些东西确实需要花很多时间),在网上找到一个好的资源真的很难。所以,是的,我完全同意。很明显,你在身边是件好事。在你的第一次测试中,我猜你的意思是System.out.println(toTest==u)代码>
Stream<Integer> numbers = Stream.of(3, 1).parallel();
BiFunction<Integer, Integer, Integer> accumulator = (a, b) -> a + b;
BiFunction<Integer, Integer, Integer> combiner = (x, y) -> x - y;
int result = numbers.reduce(
1,
accumulator,
combiner);
System.out.println(result);
int identity = 1;
int u = 3;
int toTest = combiner.apply(identity, u);
System.out.println(toTest == identity); // must be true, but is false
combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
int identity = 0;
int u = 3;
int t = 1;
boolean associativityRespected =
combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t);
System.out.println(associativityRespected); // prints false