<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      導航

      Java 流處理之收集器

      Java 流(Stream)處理操作完成之后,我們可以收集這個流中的元素,使之匯聚成一個最終結果。這個結果可以是一個對象,也可以是一個集合,甚至可以是一個基本類型數據。

      以記錄 Record 為例:

      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public static class Record {
          private String col1;
          private String col2;
          private int col3;
      }
      

      記錄 Record 包含三個屬性:列1(col1)、列2(col2)和 列3(col3)。

      創建四個記錄實例:

      Record r1 = new Record("a", "1", 1);
      Record r2 = new Record("a", "2", 2);
      Record r3 = new Record("b", "3", 3);
      Record r4 = new Record("c", "4", 4);
      

      添加到列表:

      List<Record> records = new ArrayList<>();
      
      records.add(r1);
      records.add(r2);
      records.add(r3);
      records.add(r4);
      

      收集所有記錄的 列1 值,以列表形式存儲結果

      List<String> col1List = records.stream()
              .map(Record::getCol1)
              .collect(Collectors.toList());
      log.info("col1List: {}", Json.toJson(col1List));
      

      輸出結果:

      col1List: ["a","a","b","c"]
      

      收集所有記錄的 列1 值,且去重,以集合形式存儲

      Set<String> col1Set = records.stream()
              .map(Record::getCol1)
              .collect(Collectors.toSet());
      log.info("col1Set: {}", Json.toJson(col1Set));
      

      輸出結果:

      col1Set: ["a","b","c"]
      

      收集記錄的 列2 值和 列3 值的對應關系,以字典形式存儲

      Map<String, Integer> col2Map = records.stream()
              .collect(Collectors.toMap(Record::getCol2, Record::getCol3));
      log.info("col2Map: {}", Json.toJson(col2Map));
      

      輸出結果:

      col2Map: {"1":1,"2":2,"3":3,"4":4}
      

      記錄的 列2 不能有重復值,否則會拋出 Duplicate key 異常。


      收集所有記錄中 列3 值最大的記錄

      Record max = records.stream()
              .collect(Collectors.maxBy(Comparator.comparing(Record::getCol3)))
              .orElse(null);
      log.info("max: {}", Json.toJson(max));
      

      輸出結果:

      max: {"col1":"c","col2":"4","col3":4}
      

      收集所有記錄中 列3 值的總和

      int sum = records.stream()
              .collect(Collectors.summingInt(Record::getCol3));
      log.info("sum: {}", sum);
      

      輸出結果:

      sum: 10
      

      流的收集需要通過 Stream.collect() 方法完成,方法的參數是一個 Collector(收集器);收集結果時,需要根據收集結果的目標類型,傳遞特定的收集器實例,如上:

      • Collectors.toList()
      • Collectors.toSet()
      • Collectors.toMap()
      • Collectors.maxBy()
      • Collectors.summingInt()

      Collectors(java.util.stream.Collectors) 是一個工具類,內置若干收集器,我們可以通過調用不同的方法快速獲取相應的收集器實例。

      收集器(java.util.stream.Collector)本質是一個 接口,包含以下五個方法:

      Collectors.toList() 為例演示收集器的工作過程。


      創建一個中間結果容器

      supplier() 方法會返回一個 Supplier 實例,調用該實例的 get() 方法,會創建一個中間結果容器。

      @Override
      public Supplier<List<String>> supplier() {
          return new Supplier<List<String>>() {
              @Override
              public List<String> get() {
                  List<String> container = new ArrayList<>();
      
                  return container;
              }
          };
      }
      

      考慮到收集的元素類型 String,這里的中間結果容器類型為 ArrayList。

      根據收集過程的需要,中間結果容器可以是任意的數據結構。


      逐一遍歷流中的每個元素,處理完成之后,添加到中間結果

      accumulator() 方法會返回一個 BiConsumer 實例,它有一個 accept() 方法,

      參數1:中間結果
      參數2:流中遍歷到的某個元素

      遍歷過程是 Java 自動完成的,每遍歷一個元素,會自動調用 BiConsumer.accept 方法。我們只需要在方法中實現元素的處理過程,然后把元素的處理結果添加到中間結果中就可以了。

      @Override
      public BiConsumer<List<String>, String> accumulator() {
          return new BiConsumer<List<String>, String>() {
              @Override
              public void accept(List<String> container, String col) {
                  container.add(col);
              }
          };
      }
      

      這個示例中,流中的元素不需要任何處理,直接添加至中間結果即可。


      中間結果轉換成最終結果

      finisher() 方法會返回一個 Fuction 實例,它有一個 apply() 方法,

      參數:中間結果
      返回:最終結果

      遍歷過程結束之后,Java 會自動調用 Function.apply() 方法,將中間結果轉換成最終結果。

      @Override
      public Function<List<String>, List<String>> finisher() {
          return new Function<List<String>, List<String>>() {
              @Override
              public List<String> apply(List<String> container) {
                  return container;
              }
          };
      }
      

      這個示例中,中間結果就是最終結果,不需要任何處理,直接返回中間結果即可。


      combiner()是做什么的?

      流中的元素可以被并行處理,這樣的流稱為并行流。并行流相當于把一個大流切分成多個小流,內部使用多線程,并行處理這些小流。每一個小流遍歷完成之后,都會產生一個小的中間結果,需要將這些小的中間結果合并成一個大的中間結果。

      假設有兩個小流,收集開始時,會創建兩個中間結果:

      中間結果也是通過 Supplier.get() 方法創建的。

      并行遍歷兩個小流,將各自流的處理結果添加到各自的中間結果中:

      combiner() 方法會返回一個 BinaryOperator 實例,它有一個 apply() 方法:

      參數1:中間結果1
      參數2:中間結果2
      返回:中間結果

      Java 會在合適的時機自動調用 BinaryOperator.apply() 方法,將小的中間結果合并成大的中間結果。

      @Override
      public BinaryOperator<List<String>> combiner() {
          return new BinaryOperator<List<String>>() {
              @Override
              public List<String> apply(List<String> container1, List<String> container2) {
                  container1.addAll(container2);
                  return container1;
              }
          };
      }
      

      characteristics()是什么的?

      characteristics() 會返回一個 Characteristics(枚舉)集合實例,用于設定收集器的特性,支持以下三個值:

      • CONCURRENT

        收集器支持并發使用

      • UNORDERED

        收集器不保證元素順序

      • IDENTITY_FINISH

        收集器中間結果可直接轉換成最終結果

      Java 可以根據這些特性值,保證收集器正確地、有效率地執行。


      完整代碼

      Collector<String, List<String>, List<String>> collector = new Collector<String, List<String>, List<String>>() {
          @Override
          public Supplier<List<String>> supplier() {
              return new Supplier<List<String>>() {
                  @Override
                  public List<String> get() {
                      List<String> container = new ArrayList<>();
      
                      return container;
                  }
              };
          }
      
          @Override
          public BiConsumer<List<String>, String> accumulator() {
              return new BiConsumer<List<String>, String>() {
                  @Override
                  public void accept(List<String> container, String col) {
                      container.add(col);
                  }
              };
          }
      
          @Override
          public BinaryOperator<List<String>> combiner() {
              return new BinaryOperator<List<String>>() {
                  @Override
                  public List<String> apply(List<String> container1, List<String> container2) {
                      container1.addAll(container2);
                      return container1;
                  }
              };
          }
      
          @Override
          public Function<List<String>, List<String>> finisher() {
              return new Function<List<String>, List<String>>() {
                  @Override
                  public List<String> apply(List<String> container) {
                      return container;
                  }
              };
          }
      
          @Override
          public Set<Characteristics> characteristics() {
              return new HashSet<>();
          }
      };
      
      col1List = records.stream()
              .map(Record::getCol1)
              .collect(collector);
      log.info("col1List: {}", Json.toJson(col1List));
      
      posted on 2022-09-14 10:44  非著名野生程序員  閱讀(575)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 国产99久久亚洲综合精品西瓜tv| 日韩精品成人区中文字幕| 亚洲精品www久久久久久| 中文亚洲成A人片在线观看| 久久亚洲中文字幕不卡一二区| 国产精品人伦一区二区三| 日韩一区在线中文字幕| 欧美人禽zozo动人物杂交| 久久99精品国产麻豆婷婷| 蜜臀人妻精品一区二区免费| 精品午夜福利短视频一区| 国产在线一区二区不卡| 最新国产精品拍自在线观看| 亚洲国产成人av国产自| 视频二区中文字幕在线| 亚洲av一区二区在线看| 亚洲熟妇无码爱v在线观看 | 国产激情无码一区二区三区| 十八禁午夜福利免费网站| 国产熟睡乱子伦午夜视频| 人妻夜夜爽天天爽三区丁香花 | 国产精品青草久久久久福利99| 东京热一精品无码av| 成人亚欧欧美激情在线观看| 手机在线看片不卡中文字幕| 国产区成人精品视频| 色综合一本到久久亚洲91| 亚洲aⅴ男人的天堂在线观看| 国产一区二区三区四区五区加勒比 | 人人爽人人爽人人片a免费| 国产精品无码素人福利不卡| 99久久精品国产一区色| 亚洲欧洲日产国码久在线| 狠狠色婷婷久久综合频道日韩 | 久久婷婷五月综合色国产免费观看| 国产福利社区一区二区| 国产精品国产三级国产专业| 丝袜老师办公室里做好紧好爽| av天堂午夜精品一区| 亚洲成人高清av在线| 久久国产一区二区三区|