如何将for循环转换为java8样式,但仍然跟踪索引并在循环中实例化新对象?
例如,我目前有一个块,几乎可以查找[批准,拒绝..]模式,并在修改被拒登的条目时过滤掉已批准的模式。我的逻辑是按索引检查。代码如下:
List<Obj> ret = new ArrayList<>();
for (int i = 0; i < res.size() - 1; i++) {
Obj curr = res.get(i);
Obj next = res.get(i + 1);
if (curr.getStatus().equals(APPROVED.toString()) &&
next.getStatus().equals(DISAPPROVED.toString()) {
next.setRate(null);
next.setRateDate(curr.getRateDate());
}
ret.add(curr);
}
如何使用.map()或.filter()将其转换为java8样式?
Thanksss!
编辑:迭代时不再删除
答案 0 :(得分:2)
这是你能做到这一点的最好方法。
原因:您可以创建res
的流,但是您正在根据相邻元素更改值,并且访问流中的相邻元素不会产生简单的解决方案。
来自准确reason的摘要:
Java 8流库主要用于将流拆分为较小的块以进行并行处理,因此有状态的流水线阶段非常有限,并且不支持获取当前流元素的索引和访问相邻流元素等操作。
解决这些问题的典型方法当然有一些限制,就是通过索引来驱动流。
答案 1 :(得分:1)
虽然我当然同意另一个答案,但部分答案也表明:
解决这些问题的典型方法,但有一些限制 当然是通过索引来驱动流。
因此,人们可以这样做:
List<Obj> accumulator = new ArrayList<>();
IntStream.range(0, res.size() - 1)
.mapToObj(i -> new AbstractMap.SimpleEntry<>(res.get(i), res.get(i + 1)))
.filter(entry -> entry.getKey()
.getStatus().equals(APPROVED.toString()) &&
entry.getValue()
.getStatus().equals(DISAPPROVED.toString())
.forEachOrdered(entry -> {
entry.getValue().setRate(null);
entry.getValue().setRateDate(entry.getKey().getRateDate());
accumulator.add(entry.getKey());
});
这肯定不像您当前的方法那样可读,但它是使用Java-8流API的另一种方式。