日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 8 stream的记录

發布時間:2023/12/31 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 8 stream的记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 8 stream的記錄

  • Java 8 stream
    • 1、什么是流
    • 2、如何生成流
      • 1、通過集合生成,應用中最常用的一種
      • 2、通過數組生成
      • 3、通過值生成
      • 4、通過文件生成
      • 5、通過函數生成
          • 1.iterator
          • 2.generator
    • 3、流的操作類型
    • 4、常規操作案例
        • collect 返回集合
        • reduce的介紹及用法
    • Steam之兩個list間交集、并集、差集
    • list和tree相互轉換
        • stream流式寫法把list換為Tree
      • People.java
      • Zone.java

Java 8 stream

Stream 是 Java8 中處理集合的關鍵抽象概念,它可以指定你希望對集合進行的操作,可以執行非常復雜的查找、過濾和映射數據等操作。使用Stream API 對集合數據進行操作,就類似于使用 SQL 執行的數據庫查詢。也可以使用 Stream API 來并行執行操作。簡而言之,Stream API 提供了一種高效且易于使用的處理數據的方式。

1、什么是流

流是從支持數據處理操作的源生成的元素序列,源可以是數組、文件、集合、函數。流不是集合元素,它不是數據結構并不保存數據,它的主要目的在于計算。
如果對以上函數接口不太理解的話,可參考另外一篇文章:Java 8 函數式接口
鏈接: Java 8 函數式接口

2、如何生成流

生成流的方式主要有五種

1、通過集合生成,應用中最常用的一種

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6); Stream<Integer> stream = integerList.stream();

2、通過數組生成

int[] intArr = {1, 2, 3, 4, 5, 6}; IntStream stream = Arrays.stream(intArr);

通過Arrays.stream方法生成流,并且該方法生成的流是數值流【即IntStream】而不是 Stream。補充一點使用數值流可以避免計算過程中拆箱裝箱,提高性能。

Stream API提供了mapToInt、mapToDouble、mapToLong三種方式將對象流【即Stream 】轉換成對應的數值流,同時提供了boxed方法將數值流轉換為對象流.

3、通過值生成

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

通過Stream的of方法生成流,通過Stream的empty方法可以生成一個空流.

4、通過文件生成

Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());

通過Files.line方法得到一個流,并且得到的每個流是給定文件中的一行

5、通過函數生成

1.iterator
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5);

iterate方法接受兩個參數,第一個為初始化值,第二個為進行的函數操作,因為iterator生成的流為無限流,通過limit方法對流進行了截斷,只生成5個偶數。

2.generator
Stream<Double> stream = Stream.generate(Math::random).limit(5);

generate方法接受一個參數,方法參數類型為Supplier ,由它為流提供值。generate生成的流也是無限流,因此通過limit對流進行了截斷。

3、流的操作類型

操作分類

stream操作分類
中間操作無狀態
(stateless)
unordered() fillter() map() mapToInt() peek() mapToDouble() flatMap() ...
有狀態
(staeful)
distinct() sorted() limit() skip() ...
結束操作非短路操作
(non-short-circuit operation)
forEach() forEachOrderd() toArray() reduce() collect() max() min() count() ...
短路操作
(short circuit operation)
anyMatch() allMatch() noneMatch() findFirst() findAny()

4、常規操作案例

public class StreamDemo {static List<People> list = null;//初始化數據static {list = Arrays.asList(new People("1", "Tom", 88, 90),new People("2", "Jerry", 77, 89),new People("3", "Lily", 98, 79),new People("4", "Lucy", 70, 80),new People("5", "趙二", 88, 90),new People("6", "HanMeiMei", 87, 79));}public void streamtest() {// filter 過濾器返回還是一個stream流對象//查詢math成績大于80的學生并遍歷輸出list.stream().filter(e -> e.getMath() > 80).forEach(System.out::println);//.forEach(e->System.out.println(e))//統計數量countSystem.out.println(list.stream().count());//如統計總分大于160的人數System.out.println(list.stream().filter(e -> e.getEnglish() + e.getMath() > 160).count());//limit 取前n個值list.stream().limit(3).forEach(System.out::println);//skip 跳過前n個list.stream().skip(2).forEach(System.out::println);//distinct 去除重復數據list.stream().distinct().forEach(System.out::println);//map 映射元素可以對元素進行操作 例如對每個人年齡加1list.stream().map(e -> {e.setAge(e.getAge() + 1);return e;}).forEach(System.out::println);//sorted 排序//升序list.stream().sorted((a, b) -> {return a.getEnglish().compareTo(b.getEnglish());});List<People> sortenList = list.stream().sorted(Comparator.comparing(People::getAge)).collect(Collectors.toList());//降序list.stream().sorted((a, b) -> {return b.getEnglish().compareTo(a.getEnglish());});//自定義排序:先按姓名升序,姓名相同則按年齡升序list.stream().sorted((o1, o2) -> {if (o1.getName().equals(o2.getName())) {return o1.getAge() - o2.getAge();} else {return o1.getName().compareTo(o2.getName());}}).forEach(System.out::println);List<People> sortenListDesc = list.stream().sorted(Comparator.comparing(People::getAge).reversed()).collect(Collectors.toList());//求和字段屬性為BigDecimal時:BigDecimal totalCost = list.stream().map(People::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);//返回第一個元素Optional<People> first = list.stream().findFirst();System.out.println(first.get());//返回任意一個元素System.out.println(list.stream().findAny().get());//anyMatch 是否匹配任意一元素 檢查是否包含名字為Tom的System.out.println(list.stream().anyMatch(e -> e.getName().equals("Tom")));//allMatch 是否匹配所有元素System.out.println(list.stream().allMatch(e -> e.getName().equals("Tom")));//noneMatch 是否未匹配所有元素System.out.println(list.stream().noneMatch(e -> e.getName().equals("Tom")));//findFirst 返回元素中第一個值People student = list.stream().findFirst().get();//findAny 返回元素中任意一個值People student1 = list.stream().findAny().get();//max 返回最大值 查詢英語成績最高的學生People student2 = list.stream().max((l1, l2) -> l2.getEnglish().compareTo(l1.getEnglish())).get();//min 最小值 將上面l1,l2位置對調People student3 = list.stream().max((l1, l2) -> l2.getEnglish().compareTo(l1.getEnglish())).get();/*** filter:過濾流中的某些元素* limit(n):獲取n個元素* skip(n):跳過n元素,配合limit(n)可實現分頁* distinct:通過流中元素的 hashCode() 和 equals() 去除重復元素*/Stream<Integer> stream = Stream.of(6, 4, 6, 7, 3, 9, 8, 10, 12, 14, 14);Stream<Integer> newStream = stream.filter(s -> s > 5) //6 6 7 9 8 10 12 14 14.distinct() //6 7 9 8 10 12 14.skip(2) //9 8 10 12 14.limit(2); //9 8newStream.forEach(System.out::println);/*** map:接收一個函數作為參數,該函數會被應用到每個元素上,并將其映射成一個新的元素。* flatMap:接收一個函數作為參數,將流中的每個值都換成另一個流,然后把所有流連接成一個流。* List<String> list = Arrays.asList("a,b,c", "1,2,3");*///將每個元素轉成一個新的且不帶逗號的元素Stream<String> s1 = list.stream().map(s -> s.getName().replaceAll(",", ""));s1.forEach(System.out::println); // abc 123Stream<String> s3 = list.stream().flatMap(s -> {//將每個元素轉換成一個streamString[] split = s.getName().split(",");Stream<String> s2 = Arrays.stream(split);return s2;});s3.forEach(System.out::println); // a b c 1 2 3}/**Reduce常見的用法*/public void testReduce() {Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});//求集合元素只和Integer result = stream.reduce(0, Integer::sum);System.out.println(result);stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});//求和stream.reduce((i, j) -> i + j).ifPresent(System.out::println);stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});//求最大值stream.reduce(Integer::max).ifPresent(System.out::println);stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});//求最小值stream.reduce(Integer::min).ifPresent(System.out::println);stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});//做邏輯stream.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});//求邏輯求乘機int result2 = stream.filter(i -> i % 2 == 0).reduce(1, (i, j) -> i * j);Optional.of(result2).ifPresent(System.out::println);//拼接字符串String append = list.stream().map(People::getName).reduce("拼接字符串:", String::concat);//求平均值double average = list.stream().mapToInt(People::getAge).average().orElse(0.0);//求最大值int min = list.stream().map(People::getAge).reduce(Integer::min).orElse(0);System.out.println("min : " + min);//求最小值int max = list.stream().map(People::getAge).reduce(Integer::max).orElse(0);System.out.println("max : " + max);//四種求和的方式int ageSumThree = list.stream().map(People::getAge).reduce(0, Integer::sum);System.out.println("ageSumThree: " + ageSumThree);int ageSumFive = list.stream().map(People::getAge).reduce(Integer::sum).orElse(0);System.out.println("ageSumFive: " + ageSumFive);int ageSumOne = list.stream().collect(Collectors.summingInt(People::getAge));System.out.println("ageSumOne" + ageSumOne);int ageSumFour = list.stream().mapToInt(People::getAge).sum();System.out.println("ageSumFour: " + ageSumFour);} }

collect 返回集合

/*** collect:接收一個Collector實例,將流中元素收集成另外一個數據結構。* Collector<T, A, R> 是一個接口,有以下5個抽象方法:* Supplier<A> supplier():創建一個結果容器A* BiConsumer<A, T> accumulator():消費型接口,第一個參數為容器A,第二個參數為流中元素T。* BinaryOperator<A> combiner():函數接口,該參數的作用跟上一個方法(reduce)中的combiner參數一樣,將并行流中各個子進程的運行結果(accumulator函數操作后的容器A)進行合并。* Function<A, R> finisher():函數式接口,參數為:容器A,返回類型為:collect方法最終想要的結果R。* Set<Characteristics> characteristics():返回一個不可變的Set集合,用來表明該Collector的特征。有以下三個特征:* CONCURRENT:表示此收集器支持并發。(官方文檔還有其他描述,暫時沒去探索,故不作過多翻譯)* UNORDERED:表示該收集操作不會保留流中元素原有的順序。* IDENTITY_FINISH:表示finisher參數只是標識而已,可忽略。* */ //裝成list List<Integer> ageList = list.stream().map(People::getAge).collect(Collectors.toList()); // [10, 20, 10]//轉成set Set<Integer> ageSet = list.stream().map(People::getAge).collect(Collectors.toSet()); // [20, 10]//轉成map,注:key不能相同,否則報錯 Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(People::getName, People::getAge)); // {cc=10, bb=20, aa=10}//字符串分隔符連接 String joinName = list.stream().map(People::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)//聚合操作 //1.學生總數 Long count = list.stream().collect(Collectors.counting()); //2.最大年齡 (最小的minBy同理) Integer maxAge = list.stream().map(People::getAge).collect(Collectors.maxBy(Integer::compare)).get(); //3.所有人的年齡 Integer sumAge = list.stream().collect(Collectors.summingInt(People::getAge)); //4.平均年齡 Double averageAge = list.stream().collect(Collectors.averagingDouble(People::getAge)); // 13.333333333333334 // 帶上以上所有方法 DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(People::getAge)); System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());//分組 Map<String, List<People>> collect = list.stream().collect(Collectors.groupingBy(People::getId)); //多重分組,先根據分數分再根據年齡分 Map<Integer, Map<Integer, List<People>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(People::getMath, Collectors.groupingBy(People::getAge)));//分區 //分成兩部分,一部分大于10歲,一部分小于等于10歲 Map<Boolean, List<People>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));/*List<Map<String, Object>> groupList = list2.stream().collect(Collectors.groupingBy(d -> d.get("region"))).entrySet().stream().map(d -> {Map<String, Object> map = new HashMap<>();map.put("recruitList", d.getValue());map.put("region", d.getKey());return map;}).collect(Collectors.toList());*/

reduce的介紹及用法

????Optional reduce(BinaryOperator accumulator):第一次執行時,accumulator函數的第一個參數為流中的第一個元素,第二個參數為流中元素的第二個元素;第二次執行時,第一個參數為第一次函數執行的結果,第二個參數為流中的第三個元素;依次類推。
????T reduce(T identity, BinaryOperator accumulator):流程跟上面一樣,只是第一次執行時,accumulator函數的第一個參數為identity,而第二個參數為流中的第一個元素。
???? U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator combiner):在串行流(stream)中,該方法跟第二個方法一樣,即第三個參數combiner不會起作用。在并行流(parallelStream)中,我們知道流被fork join出多個線程進行執行,此時每個線程的執行流程就跟第二個方法reduce(identity,accumulator)一樣,而第三個參數combiner函數,則是將每個線程的執行結果當成一個新的流,然后使用第一個方法reduce(accumulator)流程進行規約。

reduce參考說明

/** reduce* Optional<T> reduce(BinaryOperator<T> accumulator):* 第一次執行時,accumulator函數的第一個參數為流中的第一個元素,第二個參數為流中元素的第二個元素;第二次執行時,第一個參數為第一次函數執行的結果,第二個參數為流中的第三個元素;依次類推。** T reduce(T identity, BinaryOperator<T> accumulator):* 流程跟上面一樣,只是第一次執行時,accumulator函數的第一個參數為identity,而第二個參數為流中的第一個元素。** <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner):* 在串行流(stream)中,該方法跟第二個方法一樣,即第三個參數combiner不會起作用。在并行流(parallelStream)中,我們知道流被fork join出多個線程進行執行,* 此時每個線程的執行流程就跟第二個方法reduce(identity,accumulator)一樣,而第三個參數combiner函數,則是將每個線程的執行結果當成一個新的流,然后使用第一個方法reduce(accumulator)流程進行規約。*///經過測試,當元素個數小于24時,并行時線程數等于元素個數,當大于等于24時,并行時線程數為16List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24);Integer v = list.stream().reduce((x1, x2) -> x1 + x2).get();System.out.println(v); // 300Integer v1 = list.stream().reduce(10, (x1, x2) -> x1 + x2);System.out.println(v1); //310Integer v2 = list.stream().reduce(0,(x1, x2) -> {System.out.println("stream accumulator: x1:" + x1 + " x2:" + x2);return x1 - x2;},(x1, x2) -> {System.out.println("stream combiner: x1:" + x1 + " x2:" + x2);return x1 * x2;});System.out.println(v2); // -300Integer v3 = list.parallelStream().reduce(0,(x1, x2) -> {System.out.println("parallelStream accumulator: x1:" + x1 + " x2:" + x2);return x1 - x2;},(x1, x2) -> {System.out.println("parallelStream combiner: x1:" + x1 + " x2:" + x2);return x1 * x2;});System.out.println(v3); //197474048

Steam之兩個list間交集、并集、差集

public void listOpt() {List<String> list1 = new ArrayList();list1.add("1111");list1.add("2222");list1.add("3333");List<String> list2 = new ArrayList();list2.add("3333");list2.add("4444");list2.add("5555");// 交集List<String> intersection = list1.stream().filter(item -> list2.contains(item)).collect(Collectors.toList());System.out.println("---得到交集 intersection---");intersection.parallelStream().forEach(System.out::println);// 差集 (list1 - list2)List<String> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(Collectors.toList());System.out.println("---得到差集 reduce1 (list1 - list2)---");reduce1.parallelStream().forEach(System.out::println);// 差集 (list2 - list1)List<String> reduce2 = list2.stream().filter(item -> !list1.contains(item)).collect(Collectors.toList());System.out.println("---得到差集 reduce2 (list2 - list1)---");reduce2.parallelStream().forEach(System.out::println);// 并集List<String> listAll = list1.parallelStream().collect(Collectors.toList());List<String> listAll2 = list2.parallelStream().collect(Collectors.toList());listAll.addAll(listAll2);System.out.println("---得到并集 listAll---");listAll.parallelStream().forEach(System.out::println);// 去重并集List<String> listAllDistinct = listAll.stream().distinct().collect(Collectors.toList());System.out.println("---得到去重并集 listAllDistinct---");listAllDistinct.parallelStream().forEach(System.out::println);System.out.println("---原來的List1---");list1.parallelStream().forEach(System.out::println);System.out.println("---原來的List2---");list2.parallelStream().forEach(System.out::println);}

list和tree相互轉換

/*** list轉樹形List* @param list* @return*/public static List<Zone> list2tree(List<Zone> list) {List<Zone> result = new ArrayList<>();Map<String, Zone> map = list.stream().collect(Collectors.toMap(test -> test.getId(), test -> test));for (Zone test : list) {Zone p = map.get(test.getParentId());if (p == null) {result.add(test);} else {if (p.getChildren() == null) {p.setChildren(new ArrayList<>());}p.getChildren().add(test);}}return result;}/*** 樹形list轉list* @param list* @return*/public static List<Zone> tree2list(List<Zone> list) {List<Zone> result = new ArrayList<>();for (Zone retTreePath : list) {List<Zone> c = retTreePath.getChildren();result.add(retTreePath);if (!CollectionUtils.isEmpty(c)) {result.addAll(tree2list(c));retTreePath.setChildren(null);}}return result;}

stream流式寫法把list換為Tree

/*** 把list換為Tree** @param zoneList* @return*/public static List<Zone> listToTree(List<Zone> zoneList) {Map<String, List<Zone>> zoneByParentIdMap = zoneList.stream().collect(Collectors.groupingBy(Zone::getParentId));zoneList.forEach(zone -> zone.setChildren(zoneByParentIdMap.get(zone.getId())));return zoneList.stream().filter(v -> v.getParentId().equals("0")).collect(Collectors.toList());}

People.java

public class People {private String id;private String name;private Integer age;private Integer math;private Integer english;private BigDecimal money;private List<People> children;public People(String id, String name, Integer age,Integer math) {this.id = id;this.name = name;this.age = age;this.math=math;} }

Zone.java

public class Zone {private String id;private String name;private String parentId;private List<Zone> children;public Zone(String id, String name, String parentId) {this.id = id;this.name = name;this.parentId = parentId;}public void addChildren(Zone zone) {if (children == null) {children = new ArrayList<>();}children.add(zone);}//get set 方法 }

參考的博客:
Java 8 stream的詳細用法

JAVA stream流詳細教程

總結

以上是生活随笔為你收集整理的Java 8 stream的记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。