final Stream<Integer> numbers = Stream.of(5, 3, 2, 7, 3, 13, 7).parallel();
为什么下面这行代码的输出结果是7?
numbers.reduce(1, (a, b) -> a + b, (x, y) -> x - y));
final Stream<Integer> numbers = Stream.of(5, 3, 2, 7, 3, 13, 7).parallel();
numbers.reduce(1, (a, b) -> a + b, (x, y) -> x - y));
identity
,并且它甚至提供了一种简单的测试方法:
因此,让我们简化一下你的例子:标识值必须是组合函数的标识。这意味着对于所有的u,combiner(identity, u)等于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);
假设 u = 3
(仅为来自流的随机元素),因此:
int identity = 1;
int u = 3;
int toTest = combiner.apply(identity, u);
System.out.println(toTest == identity); // must be true, but is false
即使您认为您可以用零
替换身份,这也是可行的;然而文档提出了另一个观点:
此外,组合函数必须与累加器函数兼容。对所有的和t,以下条件必须成立:
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
reduce
中执行两个完全不同的操作,比如(a,b)->a+b
和(x,y)->x-y
是没有意义的。此外,(x, y) -> x - y
本身就违反了契约,因为它不是可结合的。令人印象深刻的是,那个网页的作者在一个例子中竟然放了这么多错误的东西... - HolgerSystem.out.println(toTest == u);
。 - Thiyagu
reduce
的契约,因为1
不是您的累加器/组合器的标识。请参见javadoc。 - Misha