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);