恐怖!深夜一乞丐在路上畫出Java Stream 知識腦圖


Java Stream 流式處理

一、流概念

1. 結構

流獲取

轉換操作 : 可以有多個

終止操作 : 只能有一個

2. 類型

stream() : 單管道

parallelStream()

多管道,并行流式處理,底層使用 ForkJoinPool 實現

強制要求有序 : forEachOrdered()

List list = Arrays.asList(1,2,3,4,5,6,7);//結果:1234567list.stream().forEach(System.out::print);//結果:5726134list.parallelStream().forEach(System.out::print);//結果:1234567list.parallelStream().forEachOrdered(System.out::print);復制代碼

3. 函數式接口

接口中有且僅有一個抽象方法

常見接口

接口參數返回值類別

ConsumerTvoid消費型接口

SupplierNoneT供給型接口

FunctionTR函數型接口

PredicateTboolean斷言型接口

4. Lambda 表達式

結構 : (參數) ‐> { 代碼語句 }

用于簡化 函數式接口 的編寫

可以延遲運行,提升性能

二、流 獲取

1. Collection 子接口

直接調用 stream() 方法

List

Set

Vector

List list =newArrayList<>();Stream stream1 = list.stream();Set set =newHashSet<>();Stream stream2 = set.stream();Vector vector =newVector<>();Stream stream3 = vector.stream();復制代碼

2. Map

不是 Collection 子接口,其 K-V 數據結構不符合流元素特征,所以需根據 Key、Value、Entry 分別獲取

Map map =newHashMap<>();// ...Stream keyStream = map.keySet().stream();Stream valueStream = map.values().stream();Stream> entryStream = map.entrySet().stream();復制代碼

3. Array

數組無法添加默認方法,故使用 Stream.of() 方法獲取

String[] array = {"張無忌","張翠山","張三豐","張一元"};Stream stream = Stream.of(array);復制代碼

二、轉換 操作

1. filter( T -> boolean )

過濾數據,保留條件為 true 的元素

List list = Arrays.asList(20,23,25,28,30,33,37,40);//從指定數據集合中過濾出大于等于30的數據集合List collect = list.stream().filter(x -> x >=30).collect(Collectors.toList());//結果:[30, 33, 37, 40]System.out.println(collect);復制代碼

2. map( T -> R )

轉換數據,將轉換后的數據存回流中

List list = Arrays.asList("1","2","3","4","5","6");List collect1 = list.stream().map(x -> Long.parseLong(x)).collect(Collectors.toList());//結果:[1, 2, 3, 4, 5, 6]System.out.println(collect1);//結果:111111list.stream().mapToInt(x -> x.length()).forEach(System.out::print);System.out.println("");//結果:111111list.stream().mapToLong(x -> x.length()).forEach(System.out::print);System.out.println("");//結果:1.01.01.01.01.01.0list.stream().mapToDouble(x -> x.length()).forEach(System.out::print);復制代碼

3. flatMap( T -> Stream )

將流中的 元素 映射為一個 流,再把每個流連接為一個流

List>? list =newArrayList>(){{? ? ? ? ? ? add(Lists.newArrayList("a","b","c"));? ? ? ? ? ? add(Lists.newArrayList("d","e","f"));? ? ? ? ? ? add(Lists.newArrayList("j","k","y"));? ? ? ? }};//結果:[[a, b, c], [d, e, f], [j, k, y]]System.out.println(list);List collect = list.stream().flatMap(List::stream).collect(Collectors.toList());//結果:[a, b, c, d, e, f, j, k, y]System.out.println(collect);復制代碼

4. distinct()

元素去重,底層使用 equals() 方法做比較

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");List collect = list.stream().distinct().collect(Collectors.toList());//結果:[a, b, ab, abc, abcd, bd]System.out.println(collect);復制代碼

5. sorted( T -> boolean )

元素排序,需事前 實現 Comparable 接口 或 自定義比較器

List list = Arrays.asList(5,3,7,1,4,6);List collect = list.stream().sorted((a, b) -> a.compareTo(b)).collect(Collectors.toList());//結果:[1, 3, 4, 5, 6, 7]System.out.println(collect);復制代碼

6. limit( num )

限制返回的元素個數

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");List collect = list.stream().limit(3).collect(Collectors.toList());//結果:[a, b, ab]System.out.println(collect);復制代碼

7. skip( num )

跳過元素

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");List collect = list.stream().skip(5).collect(Collectors.toList());//結果:[ab, a, abcd, bd, abc]System.out.println(collect);復制代碼

8. peek( T -> void )

挑出元素進行操作,但操作后的元素不返回到流中

List list = Arrays.asList("a","b","ab","abc","a","ab","a","abcd","bd","abc");//結果:abababcaabaabcdbdabclist.stream().peek(x -> x.toUpperCase()).forEach(System.out::print);//結果:ABABABCAABAABCDBDABClist.stream().map(x -> x.toUpperCase()).forEach(System.out::print);復制代碼

三、終止 操作

1. forEach

forEach : 支持并行處理

forEachOrdered : 強制要求有序處理,速度較慢

List list = Arrays.asList("a","b","ab");//結果:a b ablist.stream().forEach(x -> System.out.print(x+' '));System.out.println("");//可以簡化//結果:a b ablist.forEach(x -> System.out.print(x+' '));System.out.println("");//結果:a b ablist.stream().forEachOrdered(x -> System.out.print(x+' '));復制代碼

2. collect

toMap : 將 數據流 轉換成 Map,里面包含的元素是 key / value 形式

toSet : 將 數據流 轉換成 Set,里面包含的 元素不可重復

toList : 將 數據流 轉換成 List,里面包含的 元素有序

joining : 元素間 拼接 分割符,并返回 字符串

groupingBy : 分組,可以將 List 轉換成 Map

couting : 統計 元素數量

maxBy : 獲取 最大的元素

minBy : 獲取 最小的元素

summarizingInt : 匯總 Integer 類型的元素,返回 IntSummaryStatistics,可再調用具體方法進行統計

getCount : 統計數量

getSum : 求和

getMin : 獲取最小值

getMax : 獲取最大值

getAverage : 獲取平均值

summarizingLong : 匯總 Long 類型元素,用法同 summarizingInt

summarizingDouble : 匯總 Double 類型元素,用法同 summarizingInt

averagingInt : 獲取 Integer 元素平均值,返回一個 Double 類型數據

averagingLong : 獲取 Long 元素平均值,返回一個 Double 類型數據

averagingDouble : 獲取 Double 元素平均值,返回一個 Double 類型數據

mapping : 獲取映射,可以將原始元素的一部分內容作為一個新元素返回

List list0 = Arrays.asList("a","b","ab");Map collect0 = list0.stream().collect(Collectors.toMap(String::new, Function.identity()));//結果:{ab=ab, a=a, b=b}System.out.println(collect0);List list = Arrays.asList("a","b","ab","a","b","ab");List collect1 = list.stream().collect(Collectors.toList());//結果:

[a, b, ab, a, b, ab]System.out.println(collect1);//結果:

[a, ab, b]Set collect2 = list.stream().collect(Collectors.toSet());

System.out.println(collect2);String collect3 = list.stream().collect(Collectors.joining(","));//結果:a,b,ab,a,b,abSystem.out.println(collect3);

Map collect4 = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

//結果:{ab=2, a=2, b=2}System.out.println(collect4);

Long collect = list.stream().collect(Collectors.counting());

//結果:6System.out.println(collect);

List list1 = Arrays.asList(1,3,5,7,9,11);

Integer collect5 = list1.stream().collect(Collectors.maxBy((a, b) -> a.compareTo(b))).orElse(null);

System.out.println(collect5);

//結果:11System.out.println(collect5);

String collect6 = list1.stream().collect(Collectors.minBy((a, b) -> a.compareTo(b))).orElse(null);

//結果:1System.out.println(collect6);List list2 = Arrays.asList("2","3","5");

IntSummaryStatistics summaryStatistics = list2.stream().collect(Collectors.summarizingInt(x -> Integer.parseInt(x)));longsum = summaryStatistics.getSum();

//結果:10System.out.println(sum);

Double collect7 = list2.stream().collect(Collectors.averagingInt(x -> Integer.parseInt(x)));

//結果:3.3333333333333335System.out.println(collect7);

List userList =newArrayList() {{? add(newUser("jack",23));?

add(newUser("james",30));?

add(newUser("curry",28));}};List collect8 = userList.stream().collect(Collectors.mapping(User::getName, Collectors.toList()));

//[jack, james, curry]System.out.println(collect8);復制代碼

3. find

findFirst : 查找第一個元素,返回的類型為 Optional

findAny : 一般返回第一個元素,返回的類型為 Optional,但如果是并行情況,則不保證是第一個

List lst1 = Arrays.asList("Jhonny","David","Jack","Duke","Jill","Dany","Julia","Jenish","Divya");List lst2 = Arrays.asList("Jhonny","David","Jack","Duke","Jill","Dany","Julia","Jenish","Divya"); Optional findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();Optional fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny(); System.out.println(findFirst.get());// 總是打印出 DavidSystem.out.println(fidnAny.get());// 會隨機打印出 Jack/Jill/Julia復制代碼

4. match

allMatch : 所有元素都滿足條件,返回 boolean 類型

anyMatch : 任意一個元素滿足條件,返回 boolean 類型

noneMatch : 所有元素都不滿足條件,返回 boolean 類型

List list = Arrays.asList(2,3,5,7);booleanallMatch = list.stream().allMatch(x -> x >1);//結果:trueSystem.out.println(allMatch);booleanallMatch2 = list.stream().allMatch(x -> x >2);//結果:falseSystem.out.println(allMatch2);booleananyMatch = list.stream().anyMatch(x -> x >2);//結果:trueSystem.out.println(anyMatch);booleannoneMatch1 = list.stream().noneMatch(x -> x >5);//結果:falseSystem.out.println(noneMatch1);booleannoneMatch2 = list.stream().noneMatch(x -> x >7);//結果:trueSystem.out.println(noneMatch2);復制代碼

5. count

統計數量,返回 long 類型,與集合的 size() 方法類似

List list = Arrays.asList("a","b","ab");longcount = list.stream().count();//結果:3System.out.println(count);復制代碼

6. max、min

max : 獲取最大值,返回 Optional 類型

min : 獲取最小值,返回 Optional 類型

List list = Arrays.asList(2,3,5,7);Optional max = list.stream().max((a, b) -> a.compareTo(b));//結果:7System.out.println(max.get());Optional min = list.stream().min((a, b) -> a.compareTo(b));//結果:2System.out.println(min.get());復制代碼

7. reduce

規約操作,將整個數據流規約成一個值

兩個參數 : 循環計算的初始值、計算累加器

count、max、min 底層就是使用 reduce 實現

List list = Arrays.asList(2,3,5,7);Integer sum1 = list.stream().reduce(0, Integer::sum);//結果:17System.out.println(sum1);Optional reduce = list.stream().reduce((a, b) -> a + b);//結果:17System.out.println(reduce.get());Integer max = list.stream().reduce(0, Integer::max);//結果:7System.out.println(max);Integer min = list.stream().reduce(0, Integer::min);//結果:0System.out.println(min);Optional reduce1 = list.stream().reduce((a, b) -> a > b ? b : a);//2System.out.println(reduce1.get());復制代碼

8. toArray

數組操作,將 數據流 轉換成 數組

List list = Arrays.asList("a","b","ab");String[] strings = list.stream().toArray(String[]::new);//結果:a b abfor(inti =0; i < strings.length; i++) {? System.out.print(strings[i]+" ");}復制代碼

9. concat

將 兩個流 合并為 一個流

Stream streamA = Stream.of("張無忌");Stream streamB = Stream.of("張翠山");Stream result = Stream.concat(streamA, streamB);

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容