日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Java 8 Stream 流用法及语法

發(fā)布時間:2025/3/12 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 8 Stream 流用法及语法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java 8 Stream 流用法

1.簡介

Stream流 最全的用法
Stream 能用來干什么?用來處理集合,通過 使用Stream API 對集合數(shù)據(jù)進行操作,就類似于使用 SQL 執(zhí)行的數(shù)據(jù)庫查詢,Stream API 提供了一種高效且易于使用的處理數(shù)據(jù)的方式

為什么用Java 8 Stream ?因為 操作簡單
為什么操作簡單?因為 Lambda 表達(dá)式,它極大的提高了編程效率和程序可讀性
怎么操作流? 首先你的有個數(shù)據(jù)源(數(shù)組、集合),操作會產(chǎn)生新的流對象,原來的流對象不會改變
流用法有結(jié)束操作,這種代碼不是你寫了一個方法就執(zhí)行一個方法,而是最后觸發(fā)結(jié)束操作的時候才統(tǒng)一執(zhí)行的,collect、foreach 方法就是一種結(jié)束方法,詳情看代碼及結(jié)果參考 2.映射map、flatMap用法 部分


2.具體用法

2.1 創(chuàng)建流
// 集合創(chuàng)建流List<String> list = new ArrayList<>();// 獲取一個順序流Stream<String> listStream = list.stream();// 獲取一個并行流Stream<String> parallelListStream = list.parallelStream();// 數(shù)組創(chuàng)建流Integer[] nums = new Integer[] { 1, 2, 3, 4, 5 };Stream<Integer> arrStream = Arrays.stream(nums);arrStream.forEach(System.out::println);// 1 2 3 4 5// 靜態(tài)方法of創(chuàng)建流Stream<Integer> ofStream = Stream.of(1, 2, 3, 4, 5);ofStream.forEach(System.out::println);// 1 2 3 4 5// 靜態(tài)方法iterate 創(chuàng)建流Stream<Integer> iterateStream = Stream.iterate(1, (x) -> x + 10).limit(4);iterateStream.forEach(System.out::println); // 1 11 21 31// 靜態(tài)方法generate 創(chuàng)建流Stream<Double> generateStream = Stream.generate(Math::random).limit(2);generateStream.forEach(System.out::println);
2.2 操作流
1.過濾
  • filter:過濾流中的某些元素(可以做一些基本的判空、替換、判斷邏輯操作)
  • limit(n):獲取n個元素,結(jié)果獲取幾個元素
  • skip(n):跳過n元素,配合limit(n)可實現(xiàn)分頁
  • distinct:通過流中元素的 hashCode() 和 equals() 去除重復(fù)元素
//filter 判空Stream<Integer> notNullStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);Stream<Integer> notNullStream = notNullStreamObj.filter(i -> (null != i));notNullStream.forEach(System.out::println);//1 2 4 5 6 7 2//filter 邏輯判斷Stream<Integer> logicStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);Stream<Integer> logicStream = logicStreamObj.filter(i -> (i != null && i > 5));logicStream.forEach(System.out::println); // 6 7//filter 替換Stream<String> strStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");Stream<String> strStream = strStreamObj.filter(str -> (null != str && str.contains("a")));strStream.forEach(System.out::println); // aa ab ac//skip 跳過Stream<String> skipStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");Stream<String> skipStream = skipStreamObj.skip(2);skipStream.forEach(System.out::println); // null ac bd ee//distinct 去重Stream<String> disStreamObj = Stream.of("aa", "ab", null, "ac", "aa", "ab", null, "ee");Stream<String> disStream = disStreamObj.distinct();disStream.forEach(System.out::println); // aa ab null ac ee
2.映射
  • map:接收一個函數(shù)作為參數(shù),該函數(shù)會被應(yīng)用到每個元素上,映射成一個新的元素。
  • flatMap:接收一個函數(shù)作為參數(shù),將流中的每個值都換成另一個流,然后把所有流連接成一個流。
  • peek:這個操作很騷,類似map只不過map 是Func函數(shù),提供返回值,而peer是取出元素,Consumer表達(dá)式設(shè)值,我個人覺得沒啥區(qū)別呢,官方文檔提示:該方法主要用于調(diào)試,做一些消耗這個對象但不修改它的東西,沒啥事不要用
很想問一下 這倆map、flatMap 區(qū)別 ,細(xì)品,你細(xì)品,你細(xì)細(xì)品

map是將每個元素 映射成一個新元素,除非你過濾了,否則不會改變元素個數(shù)
flatMap是將原流中的每個值都變成另一個流,然后把流合并串起來,必須有返回值,拼裝成新的流

//map 把包含a的元素,替換成| 注意,注意, 元素還是一個整體,對每個元素Stream<String> mapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream<String> mapStream = mapStreamObj.map(str -> str.replaceAll(",", "|"));mapStream.forEach(System.out::println); // a|b|c a|e|f h|i|j//flatMap 可以把元素 切分后,再按照新元素組成新的字符串Stream<String> flatMapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream<String> flatMapStream = flatMapStreamObj.flatMap(str -> {String[] arr = str.split(",");Stream<String> result = Arrays.stream(arr);return result;});flatMapStream.forEach(System.out::println); //a b c d e f g h iSystem.out.println("1===========");Stream<String> peekStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream<String> peekStream = peekStreamObj.peek(e -> System.out.println("Filtered value: " + e)).map(String::toUpperCase).peek(e -> System.out.println("Mapped value: " + e));System.out.println("2=========== peek代碼結(jié)束,但是日志沒打印");Set<String> stringSet = peekStream.collect(Collectors.toSet());System.out.println("3=========== collect結(jié)束操作,代碼日志打印");stringSet.forEach(System.out::println);

map執(zhí)行結(jié)果

//看下執(zhí)行結(jié)果,說明 collect才是結(jié)束操作,代碼結(jié)束,但是并不是真正結(jié)束 1=========== 2=========== peek代碼結(jié)束,但是日志沒打印 Filtered value: a,b,c Mapped value: A,B,C Filtered value: a,e,f Mapped value: A,E,F Filtered value: g,h,i Mapped value: G,H,I 3=========== collect結(jié)束操作,代碼日志打印 A,B,C A,E,F G,H,I
3.排序
  • sorted():自然排序,流中元素需實現(xiàn)Comparable接口
  • sorted(Comparator com):定制排序,自定義Comparator排序器

先構(gòu)建一個User類

public static class User {private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}}

然后 看下sort用法

//按字母排序Stream<String> sortStreamObj = Stream.of("a,e,f", "a,d,c", "a,b,i");Stream<String> sortStream = sortStreamObj.sorted();sortStream.forEach(System.out::println); //abi adc aefUser u1 = new User("bb", 1);User u2 = new User("aa", 2);User u3 = new User("cc", 3);User u4 = new User("aa", 4);Set<User> userSet = Sets.newHashSet(u1, u2, u3, u4);Stream<User> userStream = userSet.stream().sorted((obj1, obj2) -> {if (obj1.getName().equals(obj2.getName())) {//name相等 按agereturn obj1.getAge() - obj2.getAge();}return obj1.getName().compareTo(obj2.getName());});userStream.forEach(System.out::println);// u2 u4 u1 u3

sort 執(zhí)行結(jié)果

a,b,i a,d,c a,e,f User{name='aa', age=2} User{name='aa', age=4} User{name='bb', age=1} User{name='cc', age=3}
4.流匹配
  • allMatch:接收一個 Predicate 函數(shù),當(dāng)流中每個元素都符合該斷言時才返回true,否則返回false
  • noneMatch:接收一個 Predicate 函數(shù),當(dāng)流中每個元素都不符合該斷言時才返回true,否則返回false
  • anyMatch:接收一個 Predicate 函數(shù),只要流中有一個元素滿足該斷言則返回true,否則返回false
  • findFirst:返回流中第一個元素
  • findAny:返回流中的任意元素
  • count:返回流中元素的總個數(shù)
  • max:返回流中元素最大值
  • min:返回流中元素最小值
List<Integer> numLists = Arrays.asList(3, 4, 5, 6, 10);// 全部匹配 - trueboolean allMatch1 = numLists.stream().allMatch(e -> e > 2); //trueSystem.out.println("allMatch1:" + allMatch1);// 全部匹配 - trueboolean allMatch2 = numLists.stream().allMatch(e -> e > 5); //falseSystem.out.println("allMatch2:" + allMatch2);// 全部都不符合 - trueboolean noneMatch = numLists.stream().noneMatch(e -> e > 20); //trueSystem.out.println("noneMatch:" + noneMatch);// 任一元素符合 - trueboolean anyMatch = numLists.stream().anyMatch(e -> e > 4); //trueSystem.out.println("anyMatch:" + anyMatch);//返回第一個Integer findFirst = numLists.stream().findFirst().get(); //3System.out.println("findFirst:" + findFirst);//返回任一個Integer findAny = numLists.stream().findAny().get(); System.out.println("findAny:" + findAny);//返回 countlong count = numLists.stream().count(); //5System.out.println("count:" + count);//返回maxInteger max = numLists.stream().max(Integer::compareTo).get(); //10System.out.println("max:" + max);//返回minInteger min = numLists.stream().min(Integer::compareTo).get();//3System.out.println("min:" + min);

匹配執(zhí)行結(jié)果

allMatch1:true allMatch2:false noneMatch:true anyMatch:true findFirst:3 findAny:3 count:5 max:10 min:3
5.組合操作
  • Reduce 就是組合操作
  • Reduce(BinaryOperator accumulator) 沒有起始值,按照運算規(guī)則進行運算操作
    解釋:第一次執(zhí)行時,accumulator函數(shù)的第一個參數(shù)為流中的第一個元素,第二個參數(shù)為流中元素的第二個元素,按照函數(shù)進行操作;
    第二次執(zhí)行時,第一個參數(shù)為第一次函數(shù)執(zhí)行操作的結(jié)果,第二個參數(shù)為流中的第三個元素;往下依次類推,返回Optinal 通過get()方法獲取結(jié)果
  • Reduce(T identity, BinaryOperator accumulator)含有初始值,第二個是第一個的變形,跟第一個方法對比,不同的是此次這個會接受一個identity參數(shù),用來指定Stream循環(huán)的初始值。如果Stream為空,就直接返回該值,特殊:該方法不會返回 Optional
Optional sumResult = Stream.of(1, 2, 3, 4).reduce((sum, item) -> {System.out.println("sum : " + sum);sum += item;System.out.println("item: " + item);System.out.println("sum+ : " + sum);System.out.println("-----——---");return sum;});System.out.println("========sumResult: " + sumResult.get());Integer sumDefineResult = Stream.of(1, 2, 3, 4).reduce(100, (sum, item) -> {System.out.println("sum : " + sum);sum += item;System.out.println("item: " + item);System.out.println("sum+ : " + sum);System.out.println("---——-----");return sum;});System.out.println("========sumDefineResult: " + sumDefineResult);

reduce 執(zhí)行結(jié)果

//下面是執(zhí)行結(jié)果 //查看執(zhí)行結(jié)果 sum : 1 item: 2 sum+ : 3 -----——--- sum : 3 item: 3 sum+ : 6 -----——--- sum : 6 item: 4 sum+ : 10 -----——--- ========sumResult: 10 sum : 100 item: 1 sum+ : 101 ---——----- sum : 101 item: 2 sum+ : 103 ---——----- sum : 103 item: 3 sum+ : 106 ---——----- sum : 106 item: 4 sum+ : 110 ---——----- ========sumDefineResult: 110
6. 收集轉(zhuǎn)換操作

這是個最最最最最基本的操作,10個流操作 9個都會使用到當(dāng)前操作

  • collect(Collectors.toList()) 轉(zhuǎn)換List
  • collect(Collectors.toSet()) 轉(zhuǎn)換Set
  • Collectors.toMap(key, value) 轉(zhuǎn)換Map ,如果key重復(fù),!!!報錯
  • Collectors.joining() join進行拼接
  • Collectors.groupingBy(key) 以Key為map的 key分組
  • Collectors.partitioningBy(規(guī)則) 以規(guī)則分區(qū) 比如 >5 ,map key為true,false
User s1 = new User("aa", 1);User s2 = new User("bb", 2);User s3 = new User("cc", 3);User s4 = new User("dd", 2);List<User> list = Arrays.asList(s1, s2, s3, s4);//轉(zhuǎn)換listList<Integer> ageList = list.stream().map(User::getAge).collect(Collectors.toList()); // [1, 2, 3]System.out.println(ageList.toString());//轉(zhuǎn)成setSet<Integer> ageSet = list.stream().map(User::getAge).collect(Collectors.toSet()); // [1, 2, 3]System.out.println(ageSet);//轉(zhuǎn)成map,注:key不能相同,否則報錯Map<String, Integer> userMap = list.stream().collect(Collectors.toMap(User::getName, User::getAge)); // {cc=10, bb=20, aa=10}System.out.println(userMap);//字符串分隔符連接String joinName = list.stream().map(User::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)System.out.println(joinName);//分組Map<Integer, List<User>> ageMap = list.stream().collect(Collectors.groupingBy(User::getAge));System.out.println(ageMap);//多重分組,先根據(jù)類型分再根據(jù)年齡分Map<Integer, Map<Integer, List<User>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getAge)));System.out.println(typeAgeMap);//分區(qū)//分成兩部分,true 一部分age大于2歲, false 一部分age小于等于2歲Map<Boolean, List<User>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 2));System.out.println(partMap);

collect 執(zhí)行結(jié)果

[1, 2, 3, 2] [1, 2, 3] {dd=2, cc=3, bb=2, aa=1} (aa,bb,cc,dd) {1=[User{name='aa', age=1}], 2=[User{name='bb', age=2}, User{name='dd', age=2}], 3=[User{name='cc', age=3}]} {1={1=[User{name='aa', age=1}]}, 2={2=[User{name='bb', age=2}, User{name='dd', age=2}]}, 3={3=[User{name='cc', age=3}]}} {false=[User{name='aa', age=1}, User{name='bb', age=2}, User{name='dd', age=2}], true=[User{name='cc', age=3}]}

總結(jié)

以上是生活随笔為你收集整理的Java 8 Stream 流用法及语法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。