gpt4 book ai didi

java - 在使用以前的元素值对每个元素执行操作后,使用 Java 8 Stream Reduce 返回列表

转载 作者:搜寻专家 更新时间:2023-10-31 19:59:56 26 4
gpt4 key购买 nike

我是 Streams 和 Reduce 的新手,所以我正在尝试并遇到了一个问题:

我有一个计数器列表,其中包含开始计数器和结束计数器。一个项目的开始计数器总是前一个的结束计数器。我有这些计数器 listItems 的列表,我想高效地循环它,过滤掉不活动的记录,然后将列表缩减为一个新列表,其中设置了所有 StartCounters。我有以下代码:

List<CounterChain> active = listItems.stream()
.filter(e -> e.getCounterStatus() == CounterStatus.ACTIVE)
.reduce(new ArrayList<CounterChain>(), (a,b) -> { b.setStartCounter(a.getEndCounter()); return b; });

但它并没有真正起作用,我有点卡住了,任何人都可以给我一些建议来帮助我完成这项工作吗?还是有同样有效的更好方法来做到这一点?谢谢!

最佳答案

缩减 将所有元素缩减为一个值。使用 (a,b) -> b 形式的缩减函数会将所有元素缩减为最后一个,因此当您想要获得包含的 List 时不合适所有(匹配的)元素。

除此之外,您正在对输入值进行修改,这违反了该操作的约定。进一步注意,该函数需要关联,即流是否执行f(f(e₁,e₂),e₃))f(e₁,f(e₂,e₃)) 使用归约函数处理三个后续流元素时。

或者,换句话说,您没有使用正确的工具来完成这项工作。

最干净的解决方案是不要混合这些不相关的操作:

List<CounterChain> active = listItems.stream()
.filter(e -> e.getCounterStatus() == CounterStatus.ACTIVE)
.collect(Collectors.toList());
for(int ix=1, num=active.size(); ix<num; ix++)
active.get(ix).setStartCounter(active.get(ix-1).getEndCounter());

第二个循环也可以使用 forEach 实现,但由于其有状态的性质,它需要一个内部类:

active.forEach(new Consumer<CounterChain>() {
CounterChain last;
public void accept(CounterChain next) {
if(last!=null) next.setStartCounter(last.getEndCounter());
last = next;
}
});

或者,使用基于索引的流:

IntStream.range(1, active.size())
.forEach(ix -> active.get(ix).setStartCounter(active.get(ix-1).getEndCounter()));

但与普通的 for 循环相比,两者都没有太多优势。

关于java - 在使用以前的元素值对每个元素执行操作后,使用 Java 8 Stream Reduce 返回列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46350402/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com