将for循环转换为java8样式

时间:2018-04-05 17:57:27

标签: java for-loop lambda java-8

如何将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!

编辑:迭代时不再删除

2 个答案:

答案 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的另一种方式。