java foreach order_Java 8流中的forEach vs forEachOrdered
我知道這些方法的執行順序不同,但在所有測試中,我都無法實現不同的執行順序。
例子:
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
請提供兩種方法產生不同輸出的示例。
試著用平行的溪流。
@是唯一可能的選擇嗎?
未指明的訂單并不意味著"保證是不同的訂單"。它只是表示未指定,這總是意味著有可能匹配遭遇順序。沒有內置的無序播放功能。
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));
第二行將始終輸出
Output:AAA
Output:BBB
Output:CCC
而第一個是不保證的,因為訂單沒有保存。forEachOrdered將按流源指定的順序處理流元素,而不管流是順序的還是并行的。
引用forEachjavadoc:
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.
當forEachOrderedjavadoc聲明(強調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.
是的,你是對的。只有并行流才有可能嗎?
即使它現在只適用于并行流——我不是說它適用于并行流——如果一些中間步驟得到優化以利用無序流,那么將來它仍然可能會中斷,例如,如果流無序,排序可能會使用不穩定的算法。
所以把forEachOrdered和parallel一起使用是沒有意義的?
@是的,沒錯。stackoverflow.com/questions/47336825/…
使用foreachored將按順序處理元素,然后使用并行流將失去并行的好處。請建議。
雖然forEach較短,看起來更漂亮,但我建議在所有需要訂單明確說明的地方使用forEachOrdered。對于順序流,forEach似乎尊重順序,甚至流API內部代碼也使用forEach(對于已知為順序流的流),在語義上需要使用forEachOrdered!然而,您可能稍后決定將流更改為并行,您的代碼將被破壞。同樣,當您使用forEachOrdered時,代碼的閱讀器會看到消息:"訂單在這里很重要"。因此,它更好地記錄了您的代碼。
還要注意,對于并行流,forEach不僅以非確定順序執行,而且還可以在不同線程中針對不同元素同時執行(這在forEachOrdered中是不可能的)。
最后,兩個forEach和forEachOrdered都很少有用。在大多數情況下,您實際上需要產生一些結果,而不僅僅是副作用,因此像reduce或collect這樣的操作應該更合適。通過forEach表達自然還原操作通常被認為是一種不好的方式。
"最后,兩個前臂/前臂合唱很少有用"。我不能再同意了。這些方法似乎用得太多了。
謝謝你的回答。但這不是現實生活中的例子。我剛學了Java 8
為什么在該代碼中使用forEachOrdered在語義上是必要的?
@Real懷疑論,它是用戶指定的流(傳遞到flatMap中)。它可以是有序的,因此必須以相同的順序放入生成的流中。
為什么?在flatMap的合同中,你看到它說它將按相同的順序放入輸出中嗎?
@真正的懷疑論者,你才是真正的懷疑論者!Stream.of("a","b","c").flatMap(s -> Stream.of("1","2","3").map(s::concat)).spliterator().hasCharacteristics(Splite??rator.ORDERED)返回true,因此必須確定生成流的順序。如果您覺得JDK文檔應該明確地說明這一點,那么可以提交一個bug。
"foreach很少有用"…至于填充一個集合,我可以理解你的觀點——但list.addAll(stream.collect(toList))不是占用了stream.forEach(list::add)兩倍的內存嗎?但是stream.forEach(this::doSomethingTotallyUnrelatedToFillingALi??st)呢?
我強烈反對江戶十一〔九〕很少使用。當您需要處理大量數據集合時,很明顯您將并行完成任務。在那里提交lambda函數非常有用。當我確實需要對結果進行排序時,我將它與IntStream一起使用;處理方法接收輸入集合,輸出將與來自該流的int一起收集,后者是兩個集合的索引。這樣,就不必使用線程安全的數據收集,這樣可以使代碼運行得更快,而且由于同步收集,所以順序仍然保持不變。
for each()方法為該流的每個元素執行一個操作。對于并行流,此操作不保證維持流的順序。
foreachored()方法對該流中的每個元素執行一個操作,確保對具有定義的遇到順序的流按遇到順序處理每個元素。
舉個例子:
String str ="sushil mittal";
System.out.println("****forEach without using parallel****");
str.chars().forEach(s -> System.out.print((char) s));
System.out.println("
****forEach with using parallel****");
str.chars().parallel().forEach(s -> System.out.print((char) s));
System.out.println("
****forEachOrdered with using parallel****");
str.chars().parallel().forEachOrdered(s -> System.out.print((char) s));
輸出:
****不使用parallel的foreach***
蘇希米塔爾
****使用parallel的foreach***
米胡爾伊斯斯塔特
****使用parallel進行foreachored***
蘇希米塔爾
總結
以上是生活随笔為你收集整理的java foreach order_Java 8流中的forEach vs forEachOrdered的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 妄想山海巨兽试炼图腾位置在哪?
- 下一篇: 上海欢乐谷过年开门吗