使用IntStream
中的range()
方法,我们可以创建对这些列表有效的索引流.
要筛选出值不相等的索引,我们可以应用filter()
运算.
将结果累积到由两个元素组成的列表中需要更多的努力.为此,我们可以使用collect(supplier,accumulator,combiner)
:
- supplier-返回新mutable container的函数.在这里,我们需要提供一个list,它应该保存减少的结果;
- accumulator-是一个函数,定义了如何将流元素添加到container中的逻辑;
- combiner-定义如何将两个容器与并行执行流时获得的部分结果合并的函数.
List<Integer> a = List.of(1, 2, 5);
List<Integer> b = List.of(1, 2, 8);
List<Integer> result = IntStream.range(0, Math.min(a.size(), b.size()))
.filter(i -> a.get(i) != b.get(i)) // filter out non-equal elements
.collect(
() -> Arrays.asList(0, 0), // supplier - provides a container which contain the results of reduction
(list, i) -> { // combiner - difines the logic on the container should be updated
if (a.get(i) > b.get(i)) list.set(0, list.get(0) + 1);
else list.set(1, list.get(1) + 1);
},
(left, right) -> { // accumulator - provides the logic for merging the two containers while executing in parallel
left.set(0, left.get(0) + right.get(0));
left.set(1, left.get(1) + right.get(1));
}
);
System.out.println(result);
Output:
[0, 1]
如果您怀疑这是解决流问题的正确方法,请查看API文档第Mutable reduction段.
即使在熟悉了上面的参考之后,你可能会认为没有collect()
也可以做到.例如,我们为什么不简单地应用filter().forEach()
来简化代码?然后看一看API文档的另一部分,它专门用于Side-effects.