JDK 8 foreach的用法
forEach
? ? ? forEach 方法接收一個 Lambda 表達式,然后在 Stream 的每一個元素上執行該表達式。
清單 ?打印姓名(forEach 和 pre-java8 的對比)
| 1 2 3 4 5 6 7 8 9 10 | // Java 8 roster.stream() .filter(p -> p.getGender() == Person.Sex.MALE) .forEach(p -> System.out.println(p.getName())); // Pre-Java 8 for (Person p : roster) { if (p.getGender() == Person.Sex.MALE) { System.out.println(p.getName()); } } |
? ? ?對一個人員集合遍歷,找出男性并打印姓名。可以看出來,forEach 是為 Lambda 而設計的,保持了最緊湊的風格。而且 Lambda 表達式本身是可以重用的,非常方便。當需要為多核系統優化時,可以 parallelStream().forEach(),只是此時原有元素的次序沒法保證,并行的情況下將改變串行時操作的行為,此時 forEach 本身的實現不需要調整,而 Java8 以前的 for 循環 code 可能需要加入額外的多線程邏輯。
? ? ? ?但一般認為,forEach 和常規 for 循環的差異不涉及到性能,它們僅僅是函數式風格與傳統 Java 風格的差別。
? ? ? ?另外一點需要注意,forEach 是 terminal 操作,因此它執行后,Stream 的元素就被“消費”掉了,你無法對一個 Stream 進行兩次 terminal 運算。下面的代碼是錯誤的:
| 1 2 | stream.forEach(element -> doOneThing(element)); stream.forEach(element -> doAnotherThing(element)); |
? ? ? 相反,具有相似功能的 intermediate 操作 peek 可以達到上述目的。如下是出現在該 api javadoc 上的一個示例。
清單 peek 對每個元素執行操作并返回一個新的 Stream
| 1 2 3 4 5 6 | Stream.of("one", "two", "three", "four") .filter(e -> e.length() > 3) .peek(e -> System.out.println("Filtered value: " + e)) .map(String::toUpperCase) .peek(e -> System.out.println("Mapped value: " + e)) .collect(Collectors.toList()); |
? ? ? ?forEach 不能修改自己包含的本地變量值,也不能用 break/return 之類的關鍵字提前結束循環。
總結
以上是生活随笔為你收集整理的JDK 8 foreach的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hackerrank Java Data
- 下一篇: apache-apollo启动报错