Stream操作Collection集合
獨(dú)立使用 Stream 的步驟如下:
1 . 使用 Stream 或 XxxStream 的 builder() 類方法創(chuàng)建該 Stream 對(duì)應(yīng)的 Builder。
2 . 重復(fù)調(diào)用 Builder 的 add() 方法向該流中添加多個(gè)元素。
3 . 調(diào)用 Builder 的 build() 方法獲取對(duì)應(yīng)的 Stream。
4 . 調(diào)用 Stream 的聚集方法。
Stream 提供了大量的聚集方法供用戶調(diào)用。對(duì)于大部分聚集方法而言,每個(gè) Stream 只能執(zhí)行一次。例如如下程序。
public class IntStreamTest {public static void main(String[] args) {IntStream is = IntStream.builder().add(20).add(13).add(-2).add(18).build();// 下面調(diào)用聚集方法的代碼每次只能執(zhí)行一行System.out.println("is 所有元素的最大值:" + is.max().getAsInt());System.out.println("is 所有元素的最小值:" + is.min().getAsInt());System.out.println("is 所有元素的總和:" + is.sum());System.out.println("is 所有元素的總數(shù):" + is.count());System.out.println("is 所有元素的平均值:" + is.average());System.out.println("is所有元素的平方是否都大于20: " + is.allMatch(ele -> ele * ele > 20));System.out.println("is是否包含任何元素的平方大于20 : " + is.anyMatch(ele -> ele * ele > 20));// 將is映射成一個(gè)新Stream,新Stream的每個(gè)元素是原Stream元素的2倍+1IntStream newIs = is.map(ele -> ele * 2 + 1);// 使用方法引用的方式來(lái)遍歷集合元素newIs.forEach(System.out::println); // 輸岀 41 27 -3 37} }上面程序先創(chuàng)建了一個(gè) IntStream,接下來(lái)分別多次調(diào)用 IntStream 的聚集方法執(zhí)行操作,這樣即可獲取該流的相關(guān)信息。
注意:上面 5~13 行代碼每次只能執(zhí)行一行,因此需要把其他代碼注釋掉。
Stream 提供了大量的方法進(jìn)行聚集操作,這些方法既可以是“中間的”(intermediate),也可以是 “末端的”(terminal)。
中間方法:中間操作允許流保持打開狀態(tài),并允許直接調(diào)用后續(xù)方法。上面程序中的 map() 方法就是中間方法。中間方法的返回值是另外一個(gè)流。
末端方法:末端方法是對(duì)流的最終操作。當(dāng)對(duì)某個(gè) Stream 執(zhí)行末端方法后,該流將會(huì)被“消耗”且不再可用。上面程序中的 sum()、count()、average() 等方法都是末端方法。
除此之外,關(guān)于流的方法還有如下兩個(gè)特征。
有狀態(tài)的方法:這種方法會(huì)給流增加一些新的屬性,比如元素的唯一性、元素的最大數(shù)量、保證元素以排序的方式被處理等。有狀態(tài)的方法往往需要更大的性能開銷。
短路方法:短路方法可以盡早結(jié)束對(duì)流的操作,不必檢查所有的元素。
Stream 常用的中間方法。
| filter(Predicate predicate) | 過(guò)濾 Stream 中所有不符合 predicate 的元素 |
| mapToXxx(ToXxxFunction mapper) | 使用 ToXxxFunction 對(duì)流中的元素執(zhí)行一對(duì)一的轉(zhuǎn)換,該方法返回的新流中包含了 ToXxxFunction 轉(zhuǎn)換生成的所有元素。 |
| peek(Consumer action) | 依次對(duì)每個(gè)元素執(zhí)行一些操作,該方法返回的流與原有流包含相同的元素。該方法主要用于調(diào)試。 |
| distinct() | 該方法用于排序流中所有重復(fù)的元素(判斷元素重復(fù)的標(biāo)準(zhǔn)是使用 equals() 比較返回 true)。這是一個(gè)有狀態(tài)的方法。 |
| sorted() | 該方法用于保證流中的元素在后續(xù)的訪問(wèn)中處于有序狀態(tài)。這是一個(gè)有狀態(tài)的方法。 |
| limit(long maxSize) | 該方法用于保證對(duì)該流的后續(xù)訪問(wèn)中最大允許訪問(wèn)的元素個(gè)數(shù)。這是一個(gè)有狀態(tài)的、短路方法。 |
Stream 常用的末端方法。
| forEach(Consumer action) | 遍歷流中所有元素,對(duì)每個(gè)元素執(zhí)行action |
| toArray() | 將流中所有元素轉(zhuǎn)換為一個(gè)數(shù)組 |
| reduce() | 該方法有三個(gè)重載的版本,都用于通過(guò)某種操作來(lái)合并流中的元素 |
| min() | 返回流中所有元素的最小值 |
| max() | 返回流中所有元素的最大值 |
| count() | 返回流中所有元素的數(shù)量 |
| anyMatch(Predicate predicate) | 判斷流中是否至少包含一個(gè)元素符合 Predicate 條件。 |
| allMatch(Predicate predicate) | 判斷流中是否每個(gè)元素都符合 Predicate 條件 |
| noneMatch(Predicate predicate) | 判斷流中是否所有元素都不符合 Predicate 條件 |
| findFirst() | 返回流中的第一個(gè)元素 |
| findAny() | 返回流中的任意一個(gè)元素 |
Collection 接口提供了一個(gè) stream() 默認(rèn)方法,該方法可返回該集合對(duì)應(yīng)的流,接下來(lái)即可通過(guò)流式 API 來(lái)操作集合元素。由于 Stream 可以對(duì)集合元素進(jìn)行整體的聚集操作,因此 Stream 極大地豐富了集合的功能。
使用 Stream 直接對(duì)集合中所有的元素進(jìn)行批量操作。下面使用 Stream 來(lái)改寫這個(gè)程序。
public class CollectionStream {public static void main(String[] args) {// 創(chuàng)建一個(gè)集合Collection objs = new HashSet();objs.add(new String("中文百度搜索Java教程"));objs.add(new String("中文百度搜索C++教程"));objs.add(new String("中文百度搜索C語(yǔ)言教程"));objs.add(new String("中文百度搜索Python教程"));objs.add(new String("中文百度搜索Go教程"));// 統(tǒng)計(jì)集合中出現(xiàn)“中文百度搜索”字符串的數(shù)量System.out.println(objs.stream().filter(ele -> ((String) ele).contains("中文百度搜索")).count()); // 輸出 5// 統(tǒng)計(jì)集合中出現(xiàn)“Java”字符串的數(shù)量System.out.println(objs.stream().filter(ele -> ((String) ele).contains("Java")).count()); // 輸出 1// 統(tǒng)計(jì)集合中出現(xiàn)字符串長(zhǎng)度大于 12 的數(shù)量System.out.println(objs.stream().filter(ele -> ((String) ele).length() > 12).count()); // 輸出 1// 先調(diào)用Collection對(duì)象的stream ()方法將集合轉(zhuǎn)換為Stream// 再調(diào)用Stream的mapToInt()方法獲取原有的Stream對(duì)應(yīng)的IntStreamobjs.stream().mapToInt(ele -> ((String) ele).length())// 調(diào)用forEach()方法遍歷IntStream中每個(gè)元素.forEach(System.out::println);// 輸出 11 11 12 10 14} }輸出結(jié)果為:
5 1 1 11 11 12 10 14從上面代碼第 11~20 行可以看出,程序只要調(diào)用 Collection 的 stream() 方法即可返回該集合對(duì)應(yīng)的 Stream,接下來(lái)就可通過(guò) Stream 提供的方法對(duì)所有集合元素進(jìn)行處理,這樣大大地簡(jiǎn)化了集合編程的代碼,這也是 Stream 編程帶來(lái)的優(yōu)勢(shì)。
上面程序中第 18 行代碼先調(diào)用 Collection 對(duì)象的 stream() 方法將集合轉(zhuǎn)換為 Stream 對(duì)象,然后調(diào)用 Stream 對(duì)象的 mapToInt() 方法將其轉(zhuǎn)換為 IntStream 這個(gè) mapToInt。方法就是一個(gè)中間方法,因此程序可繼續(xù)調(diào)用 IntStream 的 forEach() 方法來(lái)遍歷流中的元素。
總結(jié)
以上是生活随笔為你收集整理的Stream操作Collection集合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ArrayList和LinkedList
- 下一篇: Jsoup使用选择器语法来查找元素