Java8在2014年三月釋出,距離現在(2018年一月二十八號)快有四年了。我們打算將Pondus的所有生產伺服器升級到這一新版本。從那時起,我們將大部分程式碼庫遷移到lambda表示式、資料流和新的日期API上。我們也會使用Nashorn來把我們的應用中執行時發生改變的部分變成動態指令碼。
除了lambda,最實用的特性是新的資料流API。集合操作在任何我見過的程式碼庫中都隨處可見。而且對於那些集合操作,資料流是提升程式碼可讀性的好方法。
但是一件關於資料流的事情十分令我困擾:資料流只提供了幾個終止操作,例如reduce
和findFirst
屬於直接操作,其它的只能通過collect
來訪問。工具類Collctors
提供了一些便利的收集器,例如toList
、toSet
、joining
和groupingBy
。
例如,下面的程式碼對一個字串集合進行過濾,並建立新的列表:
stringCollection
.stream()
.filter(e -> e.startsWith("a"))
.collect(Collectors.toList());
複製程式碼
在遷移了300k行程式碼到資料流之後,我可以說,toList
、toSet
、和groupingBy
是你的專案中最常用的終止操作。所以我不能理解為什麼不把這些方法直接整合到Stream
介面上面,這樣你就可以直接編寫:
stringCollection
.stream()
.filter(e -> e.startsWith("a"))
.toList();
複製程式碼
這在開始看起來是個小缺陷,但是如果你需要一遍又一遍地編寫這些程式碼,它會非常煩人。
有toArray()
方法但是沒有toList()
,所以我真心希望一些便利的收集器可以在Java9中這樣新增到Stream
介面中。是吧,Brian?ಠ_ಠ
注:Stream.js是瀏覽器上的Java 8 資料流API的JavaScript介面,並解決了上述問題。所有重要的終止操作都可以直接在流上訪問,十分方便。詳情請見API文件。
無論如何,IntelliJ IDEA聲稱它是最智慧的Java IDE。所以讓我們看看如何使用IDEA來解決這一問題。
使用 IntelliJ IDEA 來幫忙
IntelliJ IDEA自帶了一個便利的特性,叫做實時模板(Live Template)。如果你還不知道它是什麼:實時模板是一些常用程式碼段的快捷方式。例如,你鍵入sout
並按下TAB鍵,IDEA就會插入程式碼段System.out.println()
。更多資訊請見這裡。
如何用實時模板來解決上述問題?實際上我們只需要為所有普遍使用的預設資料流收集器建立我們自己的實時模板。例如,我們可以建立.toList
縮寫的實時模板,來自動插入適當的收集器.collect(Collectors.toList())
。
下面是它在實際工作中的樣子:
構建你自己的實時模板
讓我們看看如何自己構建它。首先訪問設定(Settings)並在左側的選單中選擇實時模板。你也可以使用對話方塊左上角的便利的輸入過濾。
下面我們可以通過右側的+
圖示建立一個新的組,叫做Stream
。接下來我們向組中新增所有資料流相關的實時模板。我經常使用預設的收集器toList
、toSet
、groupingBy
和 join
,所以我為每個這些方法都建立了新的實時模板。
這一步非常重要。在新增新的實時模板之後,你需要在對話方塊底部指定合適的上下文。你需要選擇Java → Other
,然後定義縮寫、描述和實際的模板程式碼。
// Abbreviation: .toList
.collect(Collectors.toList())
// Abbreviation: .toSet
.collect(Collectors.toSet())
// Abbreviation: .join
.collect(Collectors.joining("$END$"))
// Abbreviation: .groupBy
.collect(Collectors.groupingBy(e -> $END$))
複製程式碼
特殊的變數$END$
指定在使用模板之後的游標位置,所以你可以直接在這個位置上打字,例如,定義連線分隔符。
提示:你應該開啟”Add unambiguous imports on the fly”(自動新增明確的匯入)選項,便於讓IDEA自動新增java.util.stream.Collectors
的匯入語句。選項在Editor → General → Auto Import
中。
讓我們在實際工作中看看這兩個模板:
連線
分組
Intellij IDEA中的實時模板非常靈活且強大。你可以用它來極大提升程式碼的生產力。你知道實時模板可以拯救生活的其它例子嗎?請在評論區留言。
仍然不滿意嗎?在我的資料流指南中學習所有你想要學到的東西。