差異處
這裏顯示兩個版本的差異處。
Both sides previous revision 前次修改 下次修改 | 前次修改 | ||
java:effective_java:lambdas_and_streams:prefer_collection_to_stream_as_a_return_type [2019/07/21 01:38] tony [Introduction & My Opinion] |
java:effective_java:lambdas_and_streams:prefer_collection_to_stream_as_a_return_type [2019/11/01 00:22] tony |
||
---|---|---|---|
行 1: | 行 1: | ||
{{tag>java effective_java}} | {{tag>java effective_java}} | ||
- | ====== Effective Java - Prefer Collection to Stream as a return type (working..) ====== | + | ====== Effective Java - Prefer Collection to Stream as a return type ====== |
===== Introduction & My Opinion ===== | ===== Introduction & My Opinion ===== | ||
如標題所示,這item希望在設計回傳type時,能傾向用Collection而不是Stream。第一個探討的是iterator的使用。假如要使用for each,你需要寫醜醜的code去做轉型,才能通過compiler: | 如標題所示,這item希望在設計回傳type時,能傾向用Collection而不是Stream。第一個探討的是iterator的使用。假如要使用for each,你需要寫醜醜的code去做轉型,才能通過compiler: | ||
行 9: | 行 9: | ||
假如要避免這種寫法,可以寫一個adapter去做這件事情;但同時你可能也會需要Stream to Interable: | 假如要避免這種寫法,可以寫一個adapter去做這件事情;但同時你可能也會需要Stream to Interable: | ||
<code java> | <code java> | ||
- | public static <E> Stream<E> streamOf(Iterable<E> iterable) { | + | public static <E> Iterable<E> iterableOf(Stream<E> stream) { |
- | return StreamSupport.stream(iterable.spliterator(), false); | + | return stream::iterator; |
} | } | ||
+ | |||
+ | for (ProcessHandle p : iterableOf(ProcessHandle.allProcesses())) { | ||
+ | // Process the process | ||
+ | } | ||
+ | |||
public static <E> Stream<E> streamOf(Iterable<E> iterable) { | public static <E> Stream<E> streamOf(Iterable<E> iterable) { | ||
return StreamSupport.stream(iterable.spliterator(), false); | return StreamSupport.stream(iterable.spliterator(), false); | ||
} | } | ||
</code> | </code> | ||
- | 在書中這裡也討論到使用Files.lines會忽略讀取時所有的例外,如果要使用這種寫法,你就必須接受這個問題。\\ | ||
\\ | \\ | ||
- | 回到method介面的設計。Collection interface除了是Iterable的sub-type外,也提供了轉stream的method。因此,如果你確定client就是要使用stream的方式,那就回傳stream;如果你無法確定,而且你是要開發通用的API,請考慮Collection或是其衍伸類別/介面。 | + | 回到method介面的設計。Collection interface除了是Iterable的sub-type外,也提供了轉stream的method。因此,如果你確定client就是要使用stream的方式,那就回傳stream;如果你無法確定,而且你是要開發通用的API,請考慮Collection或是其衍伸類別/介面。\\ |
- | + | \\ | |
- | + | 另外一個要考量的因素是效能。如果使用前面adapter轉換stream與iterator,速度會慢2.3倍;作者因特地目的而建立了collection實作,在他的實驗中會比stream快1.4倍。\\ | |
+ | \\ | ||
+ | 除了使用情況與效能需要考量外,根據我們的經驗是,有時不知使用stream後是否需要呼叫close。舉例來說,之前同事曾使用Files.list而發生file lock,root cause就是使用後沒執行close(可以參考[[https://stackoverflow.com/questions/34072035/why-is-files-lines-and-similar-streams-not-automatically-closed|link]])。因此如果要處理close,可能會讓前面提到的loop更難寫。\\ | ||
+ | \\ | ||
+ | 書中最後有提到,如果之後版本的JDK有讓Stream去繼承Iterable,那他不想用的理由就消失了;但我其中要考量的一個理由還在。 | ||
===== Note ===== | ===== Note ===== | ||
Effective Java第三版Item 47。 | Effective Java第三版Item 47。 |