這篇是Effective Java - Prefer collection to stream as a return type章節的讀書筆記 本篇的程式碼來自於原書內容
很多函式的回傳值是一系列的元素 壁如Set, List等等 你甚至在定義函式的時候不用寫死 給個Collection就搞定
Collection<String> getCollection() { return ImmutableList.of("apple", "banana", "cat"); }
如果你預期你函式的回傳值 應該要被使用者跑for-loop 你可以就讓你的回傳類型為Iterable
Iterable<String> getIterable() { return ImmutableList.of("apple", "banana", "cat");; }
如果你很不乖 很不聽話 不想用終結操作把你的stream變成Collection 你就是想要讓你的函式回傳一個Stream
Stream<String> getStream() { return ImmutableList.of("apple", "banana", "cat").stream(); }
會有什麼後果呢 就是使用你函數的人如果想要loop你的回傳值 他必須強制轉型
for (String a: (Iterable<String>)getStream()::iterator){ System.out.println(a); }
簡直醜到不能再醜了 想個別的辦法吧
余憶童稚時 能閉者眼睛寫出Adaptor
public static <E> Iterable<E> iterableOf(Stream<E> stream) { return stream::iterator; }
有了Adaptor後 人生真輕鬆
for (String a: iterableOf(getStream())){ System.out.println(a); }
太乾淨漂亮了 這就是為什麼Design Pattern要好好學
別忘了Adaptor也可以是雙向的
public static <E> Stream<E> streamOf(Iterable<E> iterable) { return StreamSupport.stream(iterable.spliterator(), false); }
當你相信大部分的使用者都會loop你的回傳值 你可以回傳Iterable 讓少數人自己寫Adaptor去做流運算
又或當你相信大部分的使用者都會繼續做Stream的運算 你可以回傳Stream 讓少數人自己寫Adaptor去做for-loop
可是大部分的情況不是簡單的二分法 要如何從中取捨呢 作者的答案是回傳Collection
原因很簡單
1.Collection具有stream()方法 可以快速的轉成Stream
2.Collection接口是Iterable的子類型
兩邊都不得罪 兩邊討好 八面玲瓏
這篇後段都是不太相關的廢話 這個篇章(Lambdas and Streams)是第三版中新出現的章節 很多小節感覺都很雜亂 講了很多跟主題不相關的廢話 不要花太多時間讀懂全部的東西 看這個部落格就可以