Java SE8中的流(Stream)

一、從迭代器(Iterator)到流(Stream)

Stream

Stream是Java SE8中新加入的類庫。流(stream)提供了一種相對於集合(collections)更高級概念的具體數據視圖。通過流的使用,你能清楚的知道你做了什麼,但關心怎麼做。它已經脫離了計算過程的實現。例如,你想計算一個已知屬性的平局值。那就列舉出數據源,屬性還有可以最優化計算的流,例如通過多線程的方式計算綜合和數量並且返回結果。
—— [翻譯自Core.Java-Volume.II.Advanced.Features.10th.Edition Character 1]

ps:在學習Stream之前,請確保你的jdk是1.8版本,並且具有一定的Lamda表達式知識。


通常來說操作一個集合,都是遍歷這個集合然後對其中的每一個元素進行操作。例如,我們想知道一段文字中長單詞的數量。
我們有如下的一段文本存在項目中的test.txt中:

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform. A key element of Spring is infrastructural support at the application level: Spring focuses on the “plumbing” of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments.
—— Spring Framework

將文件中的文本加載到內存中,並將其切割爲字符串轉換成一個List:

//從內存中加載文件中的內容
String contents = new String(Files.readAllBytes(Paths.get("test.txt")), StandardCharsets.UTF_8);
//通過空格將段落分割成單個字符串轉換成List
List<String> words = Arrays.asList(contents.split("\\PL+"));

通常來說,我們會通過遍歷的方式來取得每個元素:


long count = 0L; 
for (String w : words) {
    if (w.length() > 8) count++; 
}

如果使用流進行上面的操作:

//filter方法篩選出了符合條件(字符串長度大於8)的單次,count函數聚合了數量
 long count = words.stream() .filter(w -> w.length() > 8) .count(); 

使用流的方式看起來比遍歷更簡單,因爲你不必瞭解每次篩選和計數的過程。方法名告訴了你代碼將要執行的結果。此外,循環提供了每次操作的具體過程,流卻可以用任意你想要的方式執行,也能準確的獲取結果.


關於流

流遵循”什麼,而不是怎麼”原則。在前面的流示例中,我們描述了要做的事:獲取長單詞並且計數。我們不在意用什麼規則,在哪個線程,將要發生什麼。在差異上來說,在循環的開始就規定了一些細則尤其是計算怎麼工作,因此這會放棄很多優化的機會。

流似乎在外表上看着比集合要簡單的,他允許你變換和取回數據。但下面是一些具體的差異:
1. 流不存儲對象,這些對象可能存儲在底層的集合或者在需要的時候在產生。
2. 流的操作不改變數據源。例如篩選(filter)方法不從一個新的流中移除元素,但是他生成一個和現在不同的新流。
3. 流的操作在必要時是惰性的(lazy)。這會意味着,當需要結果的這個操作纔會被執行。例如,你只想要前五個長單詞而不是全部的,filter方法將會在獲取到五個結果的時候停止過濾.當作爲結果考慮的時,你甚至可以擁有無限的流.

下面是使用流的典型流程,你的操作應當遵守下面三條過程:
1. 創建一個流。
2. 通過一步或者很多步驟創建出中間操作的流。
3. 爲結果創建一個最終的收集方。這個操作可以是惰性的。在這之後這個流就不能再使用了。

下一篇文章會介紹如何創建一個流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章