java的Stream流學習

Liang2003發表於2024-06-26

java的Stream流(學習影片觀後感)

stream流的相關知識點分為以下五種:建立流、中間操作,聚合操作,轉換容器操作,順序流/並行流切換

1. 建立流

建立流可以透過以下幾種方式

list.stream(); //透過列表List轉為stream
Stream.of(a,b,c...);//透過Stream.of靜態方法
//還有其他與檔案有關的檔案流操作

2. 中間操作

filter // 按照表示式過濾 
map //對映,通常用於將物件某種成員變數提取出來 
sorted // 對流中元素進行排序,元素要實現比較介面,或者直接寫一個比較器作為引數
distinct //物件要重寫equals方法,基本型別不用
concat // 合併兩個流 
limit  //限制從流中獲取前n個元素
skip //跳過前n個元素

3. 聚合操作

//min,max,sum,count,average 這一類不用多說

//reduce 特殊的操作,可以自定義規則來對流操作,如將字串用逗號相連
String result = persons.stream()
    .map(Person::getName)
    .reduce("", (a, b) -> a + b + ",");//第一個引數為初始值,後面規則

此外還有些操作,是短路操作,一旦符合條件,就結束處理,無需處理整個流

有效短路操作:找到符合條件的元素時結束處理,而不會處理整個流
anymatch
noneMatch 沒有一個符合條件
allMatch 所有元素都符合條件
findFirst 返回第一個元素(返回型別為Optional,因為不確定是否為Null)
findAny 返回 任意一個元素(同上)

4. 轉換容器操作

轉換容器方法為 collect(Collector) ,Collector本身提供很多靜態轉換容器方法,如toList(),toMap()等。

List<Integer> ageList = persons.stream().map(Person::getAge).collect(Collectors.toList());

自定義Collector

ArrayList<String> collect = Stream.of("A", "C", "B", "D", "E", "F")
                .map(String::toLowerCase)
                .collect(Collector.of(
                        //Supplier
                        () -> {//定義容器型別
                            return new ArrayList<>();
                        },
                        //Accumulator 累加器
                        (list, item) -> {
                            list.add(item);
                        },
                        //combiner 用於並行流相鄰兩個資料段的合併
                        (left, right) ->
                        {
                            left.addAll(right);
                            return left;
                        }
                    // Collector.Characteristics.IDENTITY_FINISH //預設策略,將累加器結果作為最終結果
//                        Collector.Characteristics.UNORDERED //設定無序
//                        Collector.Characteristics.CONCURRENT 
                    
                ));
collect.forEach(System.out::println);

再來說一下Collector的三種配置:IDENTITY_FINISH,UNORDERED,CONCURRENT

IDENTITY_FINISH 是預設策略,將累加器結果作為最終結果

UNORDERED ,這裡無序並不是指輸出結果無序,而是不按流中元素輸入的順序執行。

CONCURRENT。預設情況下,在並行流中,流的每個分段處理結果都交給一個臨時容器,處理結束後將各個臨時容器的結果合併;而當配置CONCURRENT屬性,則所有分段共享一個容器。需要注意,如果容器不是執行緒安全的,就會忽略這條屬性。

5.順序流/並行流

Stream操作預設順序流,使用並行流需要加.parallel(),標誌後面的操作都用並行流處理。並行流的工作機制是將流分為多個段,每個段交給一個執行緒負責,然後透過合併策略(也就是上面combiner)進行合併。

ArrayList<String> collect = Stream.of("A", "C", "B", "D", "E", "F")
                .parallel() //開並行流
                .map(String::toLowerCase)
                .collect(Collector.of(
                        //Supplier
                        () -> {//定義容器型別
                            return new ArrayList<>();
                        },
                        //Accumulator 累加器
                        (list, item) -> {
                            list.add(item);
                        },
                        //combiner 用於並行流相鄰兩個資料段的合併
                        (left, right) ->
                        {
                            left.addAll(right);
                            return left;
                        }
//                      Collector.Characteristics.IDENTITY_FINISH //預設策略,將累加器結果作為最終結果
//                        Collector.Characteristics.UNORDERED //設定無序
//                        Collector.Characteristics.CONCURRENT

                ));
        collect.forEach(System.out::println);

相關文章