stream 中文稱為 「流」,通過將集合轉換為這麼一種叫做 「流」 的元素序列,通過宣告性方式,能夠對集合中的每個元素進行一系列並行或序列的流水線操作。
函式式程式設計帶來的好處尤為明顯。這種**更多地表達了業務邏輯的意圖,而不是它的實現機制。易讀的**也易於維護、更可靠、更不容易出錯。
面對一對多結構,查詢主實體時需要附帶主實體的子實體列表怎麼寫?查出主列表,迴圈差子列表
list的stream流操作可以簡化我們的**,減少程式執行的壓力,應對上面的問題,以前的話是先查出對應的list資料,然後根據取到集合中id去查詢對應的子實體中資料,接著在放入對應的集合中去,key值表示主實體的id,value值表示對應主實體id查到的結合資料,這樣就會三次foreach迴圈組裝資料,會很麻煩,當資料量大的時候,會增加程式執行的負荷,造成執行緩慢。所以,流式操作代替我們的這一堆操作,提高了**的簡易性,可維護性,可靠性,更不容易出錯。
列子
首先我們先建立乙個 person 泛型的 list
listlist = new arraylist<>();
list.add(new person("jack", 20));
list.add(new person("mike", 25));
list.add(new person("tom", 30));
person 類包含年齡和姓名兩個成員變數
private string name;
private int age;
stream() / parallelstream()
最常用到的方法,將集合轉換為流
list list = new arraylist();
// return streamlist.stream();
而 parallelstream() 是並行流方法,能夠讓資料集執行並行操作
filter(t -> boolean)
保留 boolean 為 true 的元素
保留年齡為 20 的 person 元素
list = list.stream()
.filter(person -> person.getage() == 20)
.collect(tolist());
列印輸出 [person]
collect(tolist()) 可以把流轉換為 list 型別
distinct()
去除重複元素,這個方法是通過類的 equals 方法來判斷兩個元素是否相等的
如例子中的 person 類,需要先定義好 equals 方法,不然類似[person, person] 這樣的情況是不會處理的
sorted() / sorted((t, t) -> int)
如果流中的元素的類實現了 comparable 介面,即有自己的排序規則,那麼可以直接呼叫 sorted() 方法對元素進行排序,如 stream
反之, 需要呼叫 sorted((t, t) -> int) 實現 comparator 介面
根據年齡大小來比較:
list = list.stream()
.sorted((p1, p2) -> p1.getage() - p2.getage())
.collect(tolist());
當然這個可以簡化為
list = list.stream()
.sorted(comparator.comparingint(person::getage))
.collect(tolist());
limit(long n)
返回前 n 個元素
list = list.stream()
.limit(2)
.collect(tolist());
列印輸出 [person, person]
skip(long n)
去除前 n 個元素
list = list.stream()
.skip(2)
.collect(tolist());
列印輸出 [person]
tips:
用在 limit(n) 前面時,先去除前 m 個元素再返回剩餘元素的前 n 個元素
limit(n) 用在 skip(m) 前面時,先返回前 n 個元素再在剩餘的 n 個元素中去除 m 個元素
list = list.stream()
.limit(2)
.skip(1)
.collect(tolist());
列印輸出 [person]
map(t -> r)
將流中的每乙個元素 t 對映為 r(類似型別轉換)
listnewlist = list.stream().map(person::getname).collect(tolist());
newlist 裡面的元素為 list 中每乙個 person 物件的 name 變數
flatmap(t -> stream)
將流中的每乙個元素 t 對映為乙個流,再把每乙個流連線成為乙個流
listlist = new arraylist<>();
list.add("aaa bbb ccc");
list.add("ddd eee fff");
list.add("ggg hhh iii");
list = list.stream().map(s -> s.split(" ")).flatmap(arrays::stream).collect(tolist());
上面例子中,我們的目的是把 list 中每個字串元素以" "分割開,變成乙個新的 list。
首先 map 方法分割每個字串元素,但此時流的型別為 stream,因為 split 方法返回的是 string[ ] 型別;所以我們需要使用 flatmap 方法,先使用arrays::stream將每個 string[ ] 元素變成乙個 stream流,然後 flatmap 會將每乙個流連線成為乙個流,最終返回我們需要的 stream
anymatch(t -> boolean)
流中是否有乙個元素匹配給定的 t -> boolean 條件
是否存在乙個 person 物件的 age 等於 20:
boolean b = list.stream().anymatch(person -> person.getage() == 20);
allmatch(t -> boolean)
流中是否所有元素都匹配給定的 t -> boolean 條件
nonematch(t -> boolean)
流中是否沒有元素匹配給定的 t -> boolean 條件
findany() 和 findfirst()
findany():找到其中乙個元素 (使用 stream() 時找到的是第乙個元素;使用 parallelstream() 並行時找到的是其中乙個元素)
findfirst():找到第乙個元素
值得注意的是,這兩個方法返回的是乙個 optional物件,它是乙個容器類,能代表乙個值存在或不存在,這個後面會講到
reduce((t, t) -> t) 和 reduce(t, (t, t) -> t)
用於組合流中的元素,如求和,求積,求最大值等
計算年齡總和:
int sum = list.stream().map(person::getage).reduce(0, (a, b) -> a + b);
與之相同:
int sum = list.stream().map(person::getage).reduce(0, integer::sum);
其中,reduce 第乙個引數 0 代表起始值為 0,lambda (a, b) -> a + b 即將兩值相加產生乙個新值
同樣地:
計算年齡總乘積:
int sum = list.stream().map(person::getage).reduce(1, (a, b) -> a * b);
當然也可以
optionalsum = list.stream().map(person::getage).reduce(integer::sum);
即不接受任何起始值,但因為沒有初始值,需要考慮結果可能不存在的情況,因此返回的是 optional 型別
count()
返回流中元素個數,結果為 long 型別
collect()
收集方法,我們很常用的是 collect(tolist()),當然還有 collect(toset()) 等,引數是乙個收集器介面,這個後面會另外講
foreach()
返回結果為 void,很明顯我們可以通過它來幹什麼了,比方說:
### 16. unordered()
還有這個比較不起眼的方法,返回乙個等效的無序流,當然如果流本身就是無序的話,那可能就會直接返回其本身
列印各個元素:
list.stream().foreach(system.out::println);
向資料庫插入新元素:
List的Stream流操作
stream流 stream 中文稱為 流 通過將集合轉換為這麼一種叫做 流 的元素序列,通過宣告性方式,能夠對集合中的每個元素進行一系列並行或序列的流水線操作。函式式程式設計帶來的好處尤為明顯。這種 更多地表達了業務邏輯的意圖,而不是它的實現機制。易讀的 也易於維護 更可靠 更不容易出錯。面對一對...
Stream流常用操作
stream是個好東西,用完之後感覺以前寫的一堆判斷什麼的真的太臃腫了。隨便記錄點用到的操作。把乙個list中物件某個字段值重複的合併只去乙個值,例子id重複 arraylistcollect records1.stream collect collectors.collectingandthen ...
Stream流基礎操作的學習
description stream流操作 中間操作 例如filter map peek等會對stream的中每乙個物件元素進行操作 最後返回乙個stream流 終止操作 結束乙個流的使用 不返回stream流 而是乙個物件 author zhuruilin date 2020 11 16 9 53...