Ответ 1
Использование return;
будет работать нормально. Это не помешает завершению полного цикла. Он прекратит выполнение текущей итерации цикла forEach
.
Попробуйте следующую небольшую программу:
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
stringList.stream().forEach(str -> {
if (str.equals("b")) return; // only skips this iteration.
System.out.println(str);
});
}
Вывод:
а
с
Обратите внимание, что return;
выполняется для итерации b
, но c
печатает на следующей итерации просто отлично.
Почему это работает?
Причина, по которой поведение сначала кажется неинтуитивным, состоит в том, что мы используем оператор return
, прерывающий выполнение всего метода. Поэтому в этом случае мы ожидаем, что выполнение метода main
в целом будет остановлено.
Однако необходимо понимать, что выражение лямбда, например:
str -> {
if (str.equals("b")) return;
System.out.println(str);
}
... действительно нужно рассматривать как свой собственный "метод", полностью отделенный от метода main
, несмотря на то, что он удобно расположен внутри него. Так что действительно, оператор return
останавливает выполнение выражения лямбда.
Вторая вещь, которая должна быть понята, заключается в следующем:
stringList.stream().forEach()
... на самом деле является просто нормальным циклом под обложками, который выполняет лямбда-выражение для каждой итерации.
С учетом этих двух соображений вышеуказанный код можно переписать следующим эквивалентным способом (только для образовательных целей):
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
for(String s : stringList) {
lambdaExpressionEquivalent(s);
}
}
private static void lambdaExpressionEquivalent(String str) {
if (str.equals("b")) {
return;
}
System.out.println(str);
}
При этом эквиваленте кода "менее волшебный" область действия return
становится более очевидной.