【摘要】作為一門面向對象程式設計語言,Java吸收了C++語言的優點,也展現了其強大的一面,我們能在各個地方看到其功能強大和簡單易用的兩個特征,當然,也吸引了很多程式員的注意力,是以有人想了解Java的相關内容,今天就來講講Java Stream操作Collection集合的相關内容。
Java 8 還新增了 Stream、IntStream、LongStream、DoubleStream 等流式 API,這些 API 代表多個支援串行和并行聚集操作的元素。上面 4 個接口中,Stream 是一個通用的流接口,而 IntStream、LongStream、 DoubleStream 則代表元素類型為 int、long、double 的流。
Java 8 還為上面每個流式 API 提供了對應的 Builder,例如 Stream.Builder、IntStream.Builder、LongStream.Builder、DoubleStream.Builder,開發者可以通過這些 Builder 來建立對應的流。
獨立使用 Java Stream操作Collection集合 的步驟如下:
使用 Stream 或 XxxStream 的 builder() 類方法建立該 Stream 對應的 Builder。
重複調用 Builder 的 add() 方法向該流中添加多個元素。
調用 Builder 的 build() 方法擷取對應的 Stream。
調用 Java Stream操作Collection集合 的聚集方法。
在上面 4 個步驟中,第 4 步可以根據具體需求來調用不同的方法,Stream 提供了大量的聚集方法供使用者調用,具體可參考 Stream 或 XxxStream 的 API 文檔。對于大部分聚集方法而言,每個 Stream 隻能執行一次。例如如下Java Stream操作Collection集合程式。
public class IntStreamTest {
public static void main(String[] args) {
IntStream is = IntStream.builder().add(20).add(13).add(-2).add(18).build();
// 下面調用聚集方法的代碼每次隻能執行一行
System.out.println("is 所有元素的最大值:" + is.max().getAsInt());
System.out.println("is 所有元素的最小值:" + is.min().getAsInt());
System.out.println("is 所有元素的總和:" + is.sum());
System.out.println("is 所有元素的總數:" + 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映射成一個新Stream,新Stream的每個元素是原Stream元素的2倍+1
IntStream newIs = is.map(ele -> ele * 2 + 1);
// 使用方法引用的方式來周遊集合元素
newIs.forEach(System.out::println); // 輸岀 41 27 -3 37
}
}
上面Java Stream操作Collection集合程式先建立了一個 IntStream,接下來分别多次調用 IntStream 的聚集方法執行操作,這樣即可擷取該流的相關資訊。注意:上面 5~13 行代碼每次隻能執行一行,是以需要把其他代碼注釋掉。
Stream 提供了大量的方法進行聚集操作,這些方法既可以是“中間的”(intermediate),也可以是 "末端的"(terminal)。
中間方法:中間操作允許流保持打開狀态,并允許直接調用後續方法。上面程式中的 map() 方法就是中間方法。中間方法的傳回值是另外一個流。
末端方法:末端方法是對流的最終操作。當對某個 Stream 執行末端方法後,該流将會被“消耗”且不再可用。上面程式中的 sum()、count()、average() 等方法都是末端方法。
除此之外,關于流的方法還有如下兩個特征。
有狀态的方法:這種方法會給流增加一些新的屬性,比如元素的唯一性、元素的最大數量、保證元素以排序的方式被處理等。有狀态的方法往往需要更大的性能開銷。
短路方法:短路方法可以盡早結束對流的操作,不必檢查所有的元素。
下面簡單介紹一下 Stream 常用的中間方法。
filter(Predicate predicate)過濾 Stream 中所有不符合 predicate 的元素
mapToXxx(ToXxxFunction mapper)使用 ToXxxFunction 對流中的元素執行一對一的轉換,該方法傳回的新流中包含了 ToXxxFunction 轉換生成的所有元素。
peek(Consumer action)依次對每個元素執行一些操作,該方法傳回的流與原有流包含相同的元素。該方法主要用于調試。
distinct()該方法用于排序流中所有重複的元素(判斷元素重複的标準是使用 equals() 比較傳回 true)。這是一個有狀态的方法。
sorted()該方法用于保證流中的元素在後續的通路中處于有序狀态。這是一個有狀态的方法。
limit(long maxSize)該方法用于保證對該流的後續通路中最大允許通路的元素個數。這是一個有狀态的、短路方法。
下面簡單介紹一下 Stream 常用的末端方法。
forEach(Consumer action)周遊流中所有元素,對每個元素執行action
toArray()将流中所有元素轉換為一個數組
reduce()該方法有三個重載的版本,都用于通過某種操作來合并流中的元素
min()傳回流中所有元素的最小值
max()傳回流中所有元素的最大值
count()傳回流中所有元素的數量
anyMatch(Predicate predicate)判斷流中是否至少包含一個元素符合 Predicate 條件。
allMatch(Predicate predicate)判斷流中是否每個元素都符合 Predicate 條件
noneMatch(Predicate predicate)判斷流中是否所有元素都不符合 Predicate 條件
findFirst()傳回流中的第一個元素
findAny()傳回流中的任意一個元素
除此之外,Java 8 允許使用流式 API 來操作集合,Collection 接口提供了一個 stream() 預設方法,該方法可傳回該集合對應的流,接下來即可通過流式 API 來操作集合元素。由于 Stream 可以對集合元素進行整體的聚集操作,是以 Stream 極大地豐富了集合的功能。
如果使用 Stream 可以直接對集合中所有的元素進行批量操作。下面使用 Stream 來改寫這個程式。
public class CollectionStream {
public static void main(String[] args) {
// 建立一個集合
Collection objs = new HashSet();
objs.add(new String("C語言中文網Java教程"));
objs.add(new String("C語言中文網C++教程"));
objs.add(new String("C語言中文網C語言教程"));
objs.add(new String("C語言中文網Python教程"));
objs.add(new String("C語言中文網Go教程"));
// 統計集合中出現“C語言中文網”字元串的數量
System.out.println(objs.stream().filter(ele -> ((String) ele).contains("C語言中文網")).count()); // 輸出 5
// 統計集合中出現“Java”字元串的數量
System.out.println(objs.stream().filter(ele -> ((String) ele).contains("Java")).count()); // 輸出 1
// 統計集合中出現字元串長度大于 12 的數量
System.out.println(objs.stream().filter(ele -> ((String) ele).length() > 12).count()); // 輸出 1
// 先調用Collection對象的stream ()方法将集合轉換為Stream
// 再調用Stream的mapToInt()方法擷取原有的Stream對應的IntStream
objs.stream().mapToInt(ele -> ((String) ele).length())
// 調用forEach()方法周遊IntStream中每個元素
.forEach(System.out::println);// 輸出 11 11 12 10 14
}
}
輸出結果為:
5 1 1 11 11 12 10 14
從上面Java Stream操作Collection集合代碼第 11~20 行可以看出,程式隻要調用 Collection 的 stream() 方法即可傳回該集合對應的 Stream,接下來就可通過 Stream 提供的方法對所有集合元素進行處理,這樣大大地簡化了集合程式設計的代碼,這也是 Stream 程式設計帶來的優勢。
上面程式中第 18 行代碼先調用 Collection 對象的 stream() 方法将集合轉換為 Stream 對象,然後調用 Stream 對象的 mapToInt() 方法将其轉換為 IntStream 這個 mapToInt。方法就是一個中間方法,是以程式可繼續調用 IntStream 的 forEach() 方法來周遊流中的元素。
以上就是有關Java Stream操作Collection集合的相關内容,随着我們對Java講解的深入,相信大家很慢慢了解它的功能,畢竟這是一款允許程式員以優雅的思維方式進行複雜程式設計的軟體,當然,我們還會為大家帶來更多的教學内容,請大家持續關注環球網校的相關内容,小編在此祝大家Java的學習之路順利。