我的问题是在Java 8流中编写复杂的嵌套for循环。
在我的嵌套循环中,我检查了一些条件是否满足我从列表中弹出一些元素并重新启动循环。
这是我想要重构的经典代码:
for (int i=0; i < dtoList.size(); i++){
for (int j=i+1; j < dtoList.size(); j++){
if(someVerification()){
MyDto dto1 = dtoList.get(i);
MyDto dto2 = dtoList.get(j);
dtoList.remove(dto1);
dtoList.remove(dto2);
// some other treatements ...
i=-1; // to reset the first loop
break;
}
}
}
我尝试了一些forEach代码,但它并不能满足我的要求:
IntStream.range(0,dtoList.size()).forEach(i->
{IntStream.range(0,i)).forEach(j -> { /* how to get out from the loops ??*/})})
如果算法有任何潜在的改进,欢迎使用。
答案 0 :(得分:0)
我不太确定你的嵌套循环中remove(i)
和remove(j)
背后的意图。不是一个优雅的解决方案,但与Stream相同的方法如下:
public static void main(String[] args) {
List<String> immutable = Arrays.asList("ABCDEAFABCDSDFQAA".split(""));
System.out.println("Before: " + immutable.stream().collect(Collectors.joining(",", "[", "]")));
List<String> dtoList = new ArrayList<>();
dtoList.addAll(immutable);
List<Integer> marks = new ArrayList<>();
IntStream.range(0, dtoList.size())
.filter(i -> !marks.contains(i))
.mapToObj(integer -> integer)
.flatMap(i -> IntStream.range(i+1, dtoList.size())
.mapToObj(integer -> integer)
.filter(j -> !marks.contains(j))
.map(j -> new int[]{i,j}))
.filter(ij -> !marks.contains(ij[0]))
.filter(ij -> someVerification(dtoList.get(ij[0]), dtoList.get(ij[1])))
.forEach(ij -> {
marks.add(ij[0]);
marks.add(ij[1]);
})
;
List<Object> objsToRemove = marks.stream()
.map(i -> dtoList.get(i))
.collect(Collectors.toList());
objsToRemove.forEach(obj -> dtoList.remove(obj));
System.out.println("After: " + dtoList.stream().collect(Collectors.joining(",", "[", "]")));
}
private static boolean someVerification(Object object, Object object2) {
return object.equals(object2);
}
不推荐使用Stream API的方法,因为它在forEach
上进行变异,并且最终执行取决于此副作用。