в чем разница между foreach и foreachordered java
forEach vs forEachOrdered in Java 8 Stream
I understand that these methods differ the order of execution but in all my test I cannot achieve different order execution.
Please provide examples when 2 methods will produce different outputs.
4 Answers 4
The second line will always output
whereas the first one is not guaranted since the order is not kept. forEachOrdered will processes the elements of the stream in the order specified by its source, regardless of whether the stream is sequential or parallel.
Quoting from forEach Javadoc:
The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does not guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of parallelism.
When the forEachOrdered Javadoc states (emphasis mine):
Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order.
Note also that for parallel streams the forEach not only executed in non-determenistic order, but you can also have it executed simultaneously in different threads for different elements (which is not possible with forEachOrdered ).
Finally both forEach / forEachOrdered are rarely useful. In most of the cases you actually need to produce some result, not just side-effect, thus operations like reduce or collect should be more suitable. Expressing reducing-by-nature operation via forEach is usually considered as a bad style.
forEach() method performs an action for each element of this stream. For parallel stream, this operation does not guarantee to maintain order of the stream.
forEachOrdered() method performs an action for each element of this stream, guaranteeing that each element is processed in encounter order for streams that have a defined encounter order.
take the example below:
Output:
We may lose the benefits of parallelism if we use forEachOrdered() with parallel Streams.
As we know, In parallel programming element will print parallelly if we use forEach() method. so the order will not be fixed. But In the use of forEachOrdered() fixed order in parallel Streams.
forEach vs forEachOrdered в потоке Java 8
Я понимаю, что эти методы отличаются порядком выполнения, но во всем моем тесте я не могу добиться выполнения другого порядка.
пожалуйста, приведите примеры, когда 2 методы дают различные результаты.
3 ответов
вторая строка всегда выводит
в то время как первый не гарантируется, так как заказ не сохраняется. forEachOrdered будет обрабатывать элементы потока в порядке, указанном его источником, независимо от того, является ли поток последовательным или параллельным.
поведение этой операции явно недетерминированные. Для параллельных трубопроводов потока, это операция не гарантирует уважения порядка встречи потока, так как это принесло бы в жертву преимущество параллелизма.
когда forEachOrdered Javadoc состояния (акцент мой):
выполнить действие для каждого элемента этого потока, в порядке встречи потока если поток имеет определенный порядок встречи.
Обратите также внимание, что для параллельных потоков forEach не только выполняется в недетерминированном порядке, но вы также можете выполнить его одновременно в разных потоках для разных элементов (что невозможно с forEachOrdered ).
наконец-то оба forEach / forEachOrdered редко полезно. В большинстве случаев вам действительно нужно получить какой-то результат, а не только побочный эффект, таким образом операции, как reduce или collect должен быть более подходящим. Выражая операцию уменьшения по своей природе через forEach обычно считается плохим стилем.
forEach () метод выполняет действие для каждого элемента этого потока. Для параллельного потока эта операция не гарантирует поддержание порядка потока.
forEachOrdered() метод выполняет действие для каждого элемента этого потока, гарантируя, что каждый элемент обрабатывается в порядке возникнут потоки, которые имеют определенный порядок встречи.
выход:
* * * * forEach без использования parallel****
* * * * forEach с использованием parallel****
* * * * forEachOrdered с использованием параллельного****
forEach против forEachOrdered в Java 8 Stream
Я понимаю, что эти методы различаются порядком выполнения, но во всех моих тестах я не могу добиться другого выполнения заказа.
Приведите примеры, когда два метода будут давать разные результаты.
Вторая строка всегда будет выводить
тогда как первый не гарантируется, так как порядок не соблюдается. forEachOrdered будет обрабатывать элементы потока в порядке, указанном их источником, независимо от того, является ли поток последовательным или параллельным.
Цитата из forEach Javadoc:
Поведение этой операции явно недетерминировано. Для конвейеров с параллельными потоками эта операция не гарантирует соблюдение порядка встречи потока, так как это может принести в жертву преимущества параллелизма.
Когда forEachOrdered Javadoc заявляет (выделено мной):
Выполняет действие для каждого элемента этого потока в порядке встречи потока, если у потока есть определенный порядок встречи.
Также обратите внимание, что для параллельных потоков он forEach не только выполняется в недетерминистическом порядке, но вы также можете выполнять его одновременно в разных потоках для разных элементов (что невозможно с forEachOrdered ).
Наконец, оба forEach / forEachOrdered редко полезны. В большинстве случаев вам действительно нужно получить какой-то результат, а не только побочный эффект, поэтому операции типа reduce или collect должны быть более подходящими. Выражение естественного сокращения с помощью forEach обычно считается плохим стилем.
ForEach vs forEachOrdered в потоке Java 8
Я понимаю, что эти методы отличаются порядком выполнения, но во всем моем тесте я не могу добиться выполнения другого порядка.
System.out.ln(«forEach Demo»); Stream.of(«AAA»,»BBB»,»CCC»).forEach(s->System.out.ln(«Output:»+s)); System.out.ln(«forEachOrdered Demo»); Stream.of(«AAA»,»BBB»,»CCC»).forEachOrdered(s->System.out.ln(«Output:»+s));
forEach Demo Output:AAA Output:BBB Output:CCC forEachOrdered Demo Output:AAA Output:BBB Output:CCC
пожалуйста, приведите примеры, когда 2 методы дают различные результаты.
3 ответов
вторая строка всегда выводит
Output:AAA Output:BBB Output:CCC
в то время как первый не гарантируется, так как заказ не сохраняется. forEachOrdered будет обрабатывать элементы потока в порядке, указанном его источником, независимо от того, является ли поток последовательным или параллельным.
цитирую forEach Javadoc:
поведение этой операции явно недетерминированные. Для параллельных трубопроводов потока, это операция не гарантирует уважения порядка встречи потока, так как это принесло бы в жертву преимущество параллелизма.
когда forEachOrdered Javadoc состояния (акцент мой):
выполнить действие для каждого элемента этого потока, в порядке встречи потока если поток имеет определенный порядок встречи.
хотя forEach короче и выглядит красивее, я бы посоветовал использовать forEachOrdered в каждом месте, где порядок имеет значение, чтобы явно указать это. Для последовательных потоков forEach кажется, уважает порядок и даже поток внутреннего кода API использует forEach (для потока, который, как известно, является последовательным), где семантически необходимо использовать forEachOrdered! Тем не менее позже вы можете изменить свой поток на параллельный, и ваш код будет нарушен. Также при использовании forEachOrdered читатель Вашего кода видит сообщение:»порядок имеет значение здесь». Таким образом, он документирует ваш код лучше.
Обратите также внимание, что для параллельных потоков forEach не только выполняется в недетерминированном порядке, но вы также можете выполнить его одновременно в разных потоках для разных элементов (что невозможно с forEachOrdered).
наконец-то оба forEach/forEachOrdered редко полезно. В большинстве случаев вам действительно нужно получить какой-то результат, а не только побочный эффект, таким образом операции, как reduce или collect должен быть более подходящим. Выражая операцию уменьшения по своей природе через forEach обычно считается плохим стилем.
forEach () метод выполняет действие для каждого элемента этого потока. Для параллельного потока эта операция не гарантирует поддержание порядка потока.
forEachOrdered() метод выполняет действие для каждого элемента этого потока, гарантируя, что каждый элемент обрабатывается в порядке возникнут потоки, которые имеют определенный порядок встречи.
* * * * forEach без использования parallel****
* * * * forEach с использованием parallel****
* * * * forEachOrdered с использованием параллельного****
forEach vs forEachOrdered in Java 8 Stream
The second line will always output
Output:AAA Output:BBB Output:CCC
whereas the first one is not guaranted since the order is not kept. forEachOrdered will processes the elements of the stream in the order specified by its source, regardless of whether the stream is sequential or parallel.
Quoting from forEach Javadoc:
The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does not guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of parallelism.
When the forEachOrdered Javadoc es (emphasis mine):
Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order.
answered Sep 26 ’15 at 13:13
119k4040 gold badges288288 silver badges375375 bronze badges
Although forEach shorter and looks prettier, I’d suggest to use forEachOrdered in every place where order matters to explicitly specify this. For sequential streams the forEach seems to respect the order and even stream API internal code uses forEach (for stream which is known to be sequential) where it’s semantically necessary to use forEachOrdered! Nevertheless you may later decide to change your stream to parallel and your code will be broken. Also when you use forEachOrdered the reader of your code sees the message: «the order matters here». Thus it documents your code better.
Note also that for parallel streams the forEach not only executed in non-determenistic order, but you can also have it executed simultaneously in different threads for different elements (which is not possible with forEachOrdered).
Finally both forEach/forEachOrdered are rarely useful. In most of the cases you actually need to produce some result, not just side-effect, thus operations like reduce or collect should be more suitable. Expressing reducing-by-nature operation via forEach is usually considered as a bad style.
answered Sep 26 ’15 at 13:23
Tagir ValeevTagir Valeev
88.7k1818 gold badges197197 silver badges310310 bronze badges
forEach() method performs an action for each element of this stream. For parallel stream, this operation does not guarantee to maintain order of the stream.
forEachOrdered() method performs an action for each element of this stream, guaranteeing that each element is processed in encounter order for streams that have a defined encounter order.
take the example below:
answered Jun 26 ’18 at 6:59
We may lose the benefits of parallelism if we use forEachOrdered() with parallel Streams.
As we know, In parallel programming element will parallelly if we use forEach() method. so the order will not be fixed. But In the use of forEachOrdered() fixed order in parallel Streams.
Stream.of(«AAA»,»BBB»,»CCC»).forEachOrdered(s->System.out.ln(«Output:»+s)); Output:AAA Output:BBB Output:CCC
answered Jan 17 at 5:51
30522 silver badges99 bronze badges
Not the answer you’re looking for? Browse other questions tagged java foreach java-8 java-stream or ask your own question.
Станьте мастером потоков Java. Часть 3. Операции с терминалами
Билл Гейтс однажды сказал: «Я выбираю ленивого человека для выполнения сложной работы, потому что ленивый человек найдет легкий способ сделать это». Ничто не может быть более правдивым, когда дело доходит до потоков. В этой статье вы узнаете, как Stream избегает ненужной работы, не выполняя каких-либо вычислений над исходными элементами до вызова операции терминала, и как источник генерирует только минимальное количество элементов.
Эта статья является третьей из пяти, дополненных репозиторием GitHub, содержащим инструкции и упражнения для каждого модуля.
Часть 1. Создание потоков
Часть 2: Промежуточные операции
Часть 3: Терминальные операции
Часть 4. Потоки базы данных
Часть 5: Создание приложения базы данных с использованием потоков
Терминальные операции
Теперь, когда мы знакомы с инициацией и созданием конвейера Stream, нам нужен способ обработки вывода. Терминальные операции позволяют это, производя результат от оставшихся элементов (таких как
count() ) или побочный эффект (такой как
Поток не будет выполнять какие-либо вычисления над элементами источника, пока не начнется работа терминала. Это означает, что исходные элементы потребляются только по мере необходимости — разумный способ избежать ненужной работы. Это также означает, что после применения операции терминала поток используется и дальнейшие операции не могут быть добавлены.
Давайте посмотрим, какие терминальные операции мы можем применить к концу потока Stream:
ForEach и ForEachOrdered
Возможный вариант использования потока может состоять в том, чтобы обновить свойство некоторых или всех элементов или почему бы просто не распечатать их для целей отладки. В любом случае, мы не заинтересованы в сборе или подсчете результата, а скорее в создании побочного эффекта без возврата значения.
Consumer и прекращает поток, не возвращая ничего. Разница между этими операциями просто в том, что
forEachOrdered() обещает вызвать предоставленного forEachOrdered() в порядке появления элементов в потоке, тогда как
forEach() только обещает вызвать Потребителя, но в любом порядке. Последний вариант полезен для параллельных потоков.
В простом случае, приведенном ниже, мы распечатываем каждый элемент потока в одну строку.
«Monkey», «Lion», «Giraffe», «Lemur», «Lion»
Станьте мастером потоков Java. Часть 3. Операции с терминалами
Билл Гейтс однажды сказал: «Я выбираю ленивого человека для выполнения сложной работы, потому что ленивый человек найдет легкий способ сделать это». Ничто не может быть более правдивым, когда дело доходит до потоков. В этой статье вы узнаете, как Stream избегает ненужной работы, не выполняя каких-либо вычислений над исходными элементами до вызова операции терминала, и как источник генерирует только минимальное количество элементов.
Эта статья является третьей из пяти, дополненных репозиторием GitHub, содержащим инструкции и упражнения для каждого модуля.
Часть 1. Создание потоков
Часть 2: Промежуточные операции
Часть 3: Терминальные операции
Часть 4. Потоки базы данных
Часть 5: Создание приложения базы данных с использованием потоков
Терминальные операции
Теперь, когда мы знакомы с инициацией и созданием конвейера Stream, нам нужен способ обработки вывода. Терминальные операции позволяют это, производя результат от оставшихся элементов (таких как
count() ) или побочный эффект (такой как
forEach(Consumer) ).
Поток не будет выполнять какие-либо вычисления над элементами источника, пока не начнется работа терминала. Это означает, что исходные элементы потребляются только по мере необходимости — разумный способ избежать ненужной работы. Это также означает, что после применения операции терминала поток используется и дальнейшие операции не могут быть добавлены.
Давайте посмотрим, какие терминальные операции мы можем применить к концу потока Stream:
ForEach и ForEachOrdered
Возможный вариант использования потока может состоять в том, чтобы обновить свойство некоторых или всех элементов или почему бы просто не распечатать их для целей отладки. В любом случае, мы не заинтересованы в сборе или подсчете результата, а скорее в создании побочного эффекта без возврата значения.
В простом случае, приведенном ниже, мы распечатываем каждый элемент потока в одну строку.