С функциональной точки зрения, для простых случаев они почти одинаковы, но, вообще говоря, есть некоторые скрытые различия:
- Давайте начнем с цитирования из Javadoc
forEach
для повторяемых сценариев использования, в которых указано:
выполняет заданное действие для каждого элемента Iterable до тех пор, пока все элементы не будут обработаны или действие не вызовет исключение.
а также мы можем перебирать коллекцию и выполнять заданное действие для каждого элемента - просто передав класс, реализующий интерфейс Consumer
void forEach(Consumer<? super T> action)
https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html#forEach-java.util.function.Consumer-
Порядок
Stream.forEach
является случайным, в то время как
Iterable.forEach
всегда выполняется в порядке итерации
Iterable
.
Если
Iterable.forEach
выполняет итерацию по
синхронизированной коллекции ,
Iterable.forEach
один раз берет блокировку коллекции и удерживает ее во всех вызовах метода действия.Вызов Stream.forEach использует сплитератор коллекции, который не блокирует
Действие, указанное в
Stream.forEach
, должно быть
без помех , в то время как
Iterable.forEach
разрешено устанавливать значения в базовом
ArrayList
без проблем.
В Java итераторы, возвращаемые классами Collection, например, ArrayList, HashSet, Vector и т. Д., Быстро перестают работать.Это означает, что если вы попытаетесь добавить () или удалить () из базовой структуры данных во время итерации, вы получите
ConcurrentModificationException.
https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#fail-fast
Подробнее: