在什麼情況下,我們應該在JDK 8使用舊foreach
循環在新collection.forEach()
或者是轉換每foreach
循環最好的做法?有沒有重要的性能差異?老與新的foreach循環
我能想到的唯一情況是如果你想遍歷一個數組,並且不想先將數組轉換爲列表。
在什麼情況下,我們應該在JDK 8使用舊foreach
循環在新collection.forEach()
或者是轉換每foreach
循環最好的做法?有沒有重要的性能差異?老與新的foreach循環
我能想到的唯一情況是如果你想遍歷一個數組,並且不想先將數組轉換爲列表。
由於JDK 8還沒有發佈,所以現在很難考慮最佳實踐。但是,基於這些API的早期使用,有一些有趣的觀察。
forEach()
方法現在在Iterable
上,它由Collection
繼承,所以所有集合都可以使用forEach()
。
一個數組可以用Arrays.asList()
或與Arrays.stream()
流合併在一個集合中。這些只是包裝;他們不會將所有元素複製到新的容器中。
關於性能的Iterable.forEach(action)
默認的實現僅僅是通常的「增強的for循環」,它創建了一個迭代器和問題連續hasNext()
和next()
調用和調用一個循環內的action
方法。與裸增強for循環相比,額外方法調用有一點額外開銷,但它可能非常小。
我會選擇文體的理由,而不是性能。
可能不值得將轉換爲 enhanced-for循環使用forEach()
。試想一下:
for (String s : coll) {
System.out.println("---");
System.out.println(s);
System.out.println("---");
}
與
coll.forEach(s -> {
System.out.println("---");
System.out.println(s);
System.out.println("---");
});
如果拉姆達是一個真實的班輪它可能是值得的,但在我看來內forEach()
多行語句拉姆達並不比更清晰一個很好的for循環。但是,如果for循環的主體中包含邏輯,或者如果它需要保持某種運行狀態,則可能需要將循環重新轉換爲流管道。考慮這個片段,發現一個集合中的最長的字符串的長度:
int longest = -1;
for (String s : strings) {
int len = s.length();
if (len > longest)
longest = len;
}
使用lambda表達式和流庫改寫,它應該是這樣的:
OptionalInt longest =
strings.stream()
.mapToInt(s -> s.length())
.max();
這是新的和不熟悉的當然,但經過這一段時間,我發現它簡潔易讀。
創建一個parallelStream()或一個stream()然後調用forEach的好處如何? – MohamedSanaulla
是的,使用流確實可以提供更簡單的並行性。然而,最初的問題是關於'Collection.forEach'(真的,'Iterable.forEach'),它隱含地是連續的,有序的,並且有副作用。將每個循環改爲並行流可能涉及很多工作,並不一定是一個簡單的重構。 –
請注意,'forEach()'已移至'Iterable',但它仍由'Collection'繼承。 –