Я понимаю, что эти методы различаются порядком выполнения, но во всех моих тестах я не могу добиться другого выполнения заказа.
Пример:
System.out.println("forEach Demo");
Stream.of("AAA","BBB","CCC").forEach(s->System.out.println("Output:"+s));
System.out.println("forEachOrdered Demo");
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s));
Выход:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
Приведите примеры, когда два метода будут давать разные результаты.
java
foreach
java-8
java-stream
gstackoverflow
источник
источник
Ответы:
Stream.of("AAA","BBB","CCC").parallel().forEach(s->System.out.println("Output:"+s)); Stream.of("AAA","BBB","CCC").parallel().forEachOrdered(s->System.out.println("Output:"+s));
Вторая строка всегда будет выводить
тогда как первый не гарантируется, так как порядок не соблюдается.
forEachOrdered
будет обрабатывать элементы потока в порядке, указанном их источником, независимо от того, является ли поток последовательным или параллельным.Цитата из
forEach
Javadoc:Когда
forEachOrdered
Javadoc заявляет (выделено мной):источник
forEachOrdered
сparallel
?Хотя он
forEach
короче и выглядит красивее, я предлагаю использовать егоforEachOrdered
в любом месте, где важен порядок, чтобы явно указать это. Для последовательных потоков,forEach
похоже, соблюдается порядок и даже используется внутренний код API потокаforEach
(для потока, который, как известно, является последовательным), где это семантически необходимо использоватьforEachOrdered
! Тем не менее, позже вы можете решить изменить свой поток на параллельный, и ваш код будет сломан. Также, когда вы используетеforEachOrdered
программу для чтения вашего кода, вы увидите сообщение: «Здесь важен порядок». Таким образом он лучше документирует ваш код.Также обратите внимание, что для параллельных потоков он
forEach
не только выполняется в недетерминистическом порядке, но вы также можете выполнять его одновременно в разных потоках для разных элементов (что невозможно сforEachOrdered
).Наконец, оба
forEach
/forEachOrdered
редко полезны. В большинстве случаев вам действительно нужно получить какой-то результат, а не только побочный эффект, поэтому операции типаreduce
илиcollect
должны быть более подходящими. Выражение естественного сокращения с помощьюforEach
обычно считается плохим стилем.источник
forEachOrdered
в этом коде?flatMap
). Его можно заказать, поэтому он должен быть помещен в результирующий поток в том же порядке.Stream.of("a", "b", "c").flatMap(s -> Stream.of("1", "2", "3").map(s::concat)).spliterator().hasCharacteristics(Spliterator.ORDERED)
возвращает true, поэтому необходимо определить порядок результирующего потока. Если вы считаете, что документация JDK должна прямо об этом сказать, не стесняйтесь сообщать об ошибке.forEach()
выполняет действие для каждого элемента этого потока. Для параллельного потока эта операция не гарантирует поддержание порядка потока.forEachOrdered()
выполняет действие для каждого элемента этого потока, гарантируя, что каждый элемент обрабатывается в порядке встречи для потоков, которые имеют определенный порядок встречи.возьмите пример ниже:
String str = "sushil mittal"; System.out.println("****forEach without using parallel****"); str.chars().forEach(s -> System.out.print((char) s)); System.out.println("\n****forEach with using parallel****"); str.chars().parallel().forEach(s -> System.out.print((char) s)); System.out.println("\n****forEachOrdered with using parallel****"); str.chars().parallel().forEachOrdered(s -> System.out.print((char) s));
Выход:
источник