У меня проблема с потоком Java 8 foreach, пытающимся перейти к следующему элементу в цикле. Я не могу установить команду вроде continue;
, только return;
работает, но в этом случае вы выйдете из цикла. Мне нужно перейти к следующему элементу цикла. Как я могу это сделать?
Пример (не работает):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).foreach(line -> {
...
if(...)
continue; // this command doesn't working here
});
}
Пример (рабочий):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).collect(Collectors.toList());
}
for(String filteredLine : filteredLines){
...
if(...)
continue; // it's working!
}
continue
любом случае не будет перехода к следующему элементу без каких-либо функциональных изменений.else
блок. Если после этого ничего нетcontinue
, отбросьте блок if и continue: они бесполезны.Ответы:
Использование
return;
будет работать нормально. Это не помешает завершению полного цикла. Он остановит выполнение только текущей итерацииforEach
цикла.Попробуйте следующую небольшую программу:
Вывод:
Обратите внимание, как
return;
выполняется дляb
итерации, ноc
на следующей итерации печатается нормально.Почему это работает?
Причина, по которой поведение сначала кажется неинтуитивным, заключается в том, что мы привыкли, что
return
оператор прерывает выполнение всего метода. Таким образом, в этом случае мы ожидаем, чтоmain
выполнение метода в целом будет остановлено.Однако следует понимать, что лямбда-выражение, например:
... действительно нужно рассматривать как отдельный «метод», полностью отдельный от
main
метода, несмотря на то, что он удобно расположен внутри него. На самом делеreturn
оператор останавливает выполнение только лямбда-выражения.Второе, что необходимо понять, это то, что:
... на самом деле это просто обычный скрытый цикл, который выполняет лямбда-выражение для каждой итерации.
С учетом этих двух моментов приведенный выше код можно переписать следующим эквивалентным способом (только в образовательных целях):
С этим «менее магическим» эквивалентом кода область действия
return
оператора становится более очевидной.источник
Другое решение: пройдите фильтр с вашими перевернутыми условиями: Пример:
можно заменить на
Кажется, что самый простой подход - использовать return; хотя.
источник
Лямбда, которую вы передаете,
forEach()
оценивается для каждого элемента, полученного из потока. Сама итерация не видна из области лямбда-выражения, поэтому вы не можетеcontinue
ее использовать, как если быforEach()
это был макрос препроцессора C. Вместо этого вы можете условно пропустить остальные инструкции в нем.источник
Вы можете использовать простой
if
оператор вместо continue. Поэтому вместо того, как у вас есть код, вы можете попробовать:Предикат в операторе if будет просто противоположен предикату в вашем
if(pred) continue;
операторе, поэтому просто используйте!
(логическое не).источник