List的Stream流操作

2021-10-12 02:35:24 字數 4922 閱讀 9750

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...