Java中Stream的teeing()方法用於處理合並兩個Collector - foojay

發表於2021-05-14

什麼是teeing()方法?

返回一個由兩個下游collectors組成的Collector。傳遞到結果collectors中的每個元素都是由兩個下游collectors處理的,然後使用指定的合併merge功能將它們的結果合併到最終結果中。

產生的Collector函式執行以下操作:

  • supplier提供者:建立一個結果容器,其中包含通過呼叫每個collector的supplier而獲得的結果容器
  • accumulator累加器:使用其結果容器和輸入元素呼叫每個collector的累加器
  • combiner組合器:使用兩個結果容器呼叫每個collector的組合器
  • finisher整理器:使用其結果容器呼叫每個collector的整理器,然後呼叫提供的合併並返回其結果。

針對在Stream流收集器的購物車DDD聚合真實示例 - foojay中案例:我們使用兩個簡單的Collector實現代替我們的自定義Collector,一個實現價格行的聚合,另一個購物車的價格彙總聚合。

public PriceAndRows getPriceAndRows(Cart cart) {
  return cart.getProducts()
      .entrySet()
      .stream()
      .map(CartRow::new)                           // 1
      .collect(Collectors.teeing(                  // 2
          Collectors.reducing(                     // 3
              BigDecimal.ZERO,                     // 3.1
              CartRow::getRowPrice,                // 3.2
              BigDecimal::add),                    // 3.3
          Collectors.toList(),                     // 4
          PriceAndRows::new                        // 5
      ));
}

  1. 對映每個Entry到一個CartRow
  2. 呼叫teeing()方法
  3. 第一個collector收集器計算價格。這是一個簡單的reducing()呼叫,具有:起始元素;從CartRow提取Price;使用BinaryOperator將兩個價格加在一起
  4. 第二個收集器將彙總CartRow到一個列表中
  5. 最後,最後一個引數建立一個新物件,該物件彙總來自第一個和第二個收集器的結果

在實現方面,teeing():

  1. 提取兩個Collector中單個元件,即,supplier(), accumulator(), combiner() and finisher()`
  2. 並排配對
  3. 通過傳遞配對來建立一個新的Collector

原始碼: Github

    相關文章