当在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?
})

当前回答

public static void main(String[] args) {
    List<String> list = Arrays.asList("one", "two", "three", "seven", "nine");
    AtomicBoolean yes = new AtomicBoolean(true);
    list.stream().takeWhile(value -> yes.get()).forEach(value -> {
        System.out.println("prior cond" + value);
        if (value.equals("two")) {
            System.out.println(value);
            yes.set(false);
        }

    });
    //System.out.println("Hello World");
}

其他回答

您要么需要使用一个使用谓词指示是否继续的方法(因此它有break代替),要么需要抛出一个异常——当然,这是一种非常丑陋的方法。

所以你可以这样写forEachConditional方法:

public static <T> void forEachConditional(Iterable<T> source,
                                          Predicate<T> action) {
    for (T item : source) {
        if (!action.test(item)) {
            break;
        }
    }
}

与Predicate<T>不同,您可能希望使用相同的通用方法(接受T并返回bool值)定义自己的函数接口,但使用名称更清楚地表明期望—Predicate<T>在这里不是理想的。

更新到Java 9+与takeWhile:

MutableBoolean ongoing = MutableBoolean.of(true);
someobjects.stream()...takeWhile(t -> ongoing.value()).forEach(t -> {
    // doing something.
    if (...) { // want to break;
        ongoing.setFalse();
    }
});
public static void main(String[] args) {
    List<String> list = Arrays.asList("one", "two", "three", "seven", "nine");
    AtomicBoolean yes = new AtomicBoolean(true);
    list.stream().takeWhile(value -> yes.get()).forEach(value -> {
        System.out.println("prior cond" + value);
        if (value.equals("two")) {
            System.out.println(value);
            yes.set(false);
        }

    });
    //System.out.println("Hello World");
}

lambda中的return等于for-each中的continue,但不等同于break。你可以直接返回继续:

someObjects.forEach(obj -> {
   if (some_condition_met) {
      return;
   }
})

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

someObjects.allMatch(obj -> {
    return !some_condition_met;
});