当在Iterable上使用外部迭代时,我们使用break或return from enhanced for-each循环,如下:

for (SomeObject obj : someObjects) {
   if (some_condition_met) {
      break; // or return obj
   }
}

如何在Java 8 lambda表达式中使用内部迭代中断或返回:

someObjects.forEach(obj -> {
   //what to do here?
})

当前回答

如果你需要这个,你不应该使用forEach,而是在流上可用的其他方法之一;哪一个,取决于你的目标是什么。

例如,如果这个循环的目标是找到与某个谓词匹配的第一个元素:

Optional<SomeObject> result =
    someObjects.stream().filter(obj -> some_condition_met).findFirst();

(注意:这不会遍历整个集合,因为流是惰性计算的——它将在第一个匹配条件的对象处停止)。

如果你只想知道集合中是否有一个元素的条件为真,你可以使用anyMatch:

boolean result = someObjects.stream().anyMatch(obj -> some_condition_met);

其他回答

这个呢:

final BooleanWrapper condition = new BooleanWrapper();
someObjects.forEach(obj -> {
   if (condition.ok()) {
     // YOUR CODE to control
     condition.stop();
   }
});

其中,BooleanWrapper是一个必须实现以控制流的类。

下面是我在一个项目中使用的解决方案。相反,forEach只需使用allMatch:

someObjects.allMatch(obj -> {
    return !some_condition_met;
});
int valueToMatch = 7;
Stream.of(1,2,3,4,5,6,7,8).anyMatch(val->{
   boolean isMatch = val == valueToMatch;
   if(isMatch) {
      /*Do whatever you want...*/
       System.out.println(val);
   }
   return isMatch;
});

它只会在找到匹配的地方执行操作,在找到匹配后停止迭代。

更新到Java 9+与takeWhile:

MutableBoolean ongoing = MutableBoolean.of(true);
someobjects.stream()...takeWhile(t -> ongoing.value()).forEach(t -> {
    // doing something.
    if (...) { // want to break;
        ongoing.setFalse();
    }
});

如果你需要这个,你不应该使用forEach,而是在流上可用的其他方法之一;哪一个,取决于你的目标是什么。

例如,如果这个循环的目标是找到与某个谓词匹配的第一个元素:

Optional<SomeObject> result =
    someObjects.stream().filter(obj -> some_condition_met).findFirst();

(注意:这不会遍历整个集合,因为流是惰性计算的——它将在第一个匹配条件的对象处停止)。

如果你只想知道集合中是否有一个元素的条件为真,你可以使用anyMatch:

boolean result = someObjects.stream().anyMatch(obj -> some_condition_met);