Java中Stream的teeing()方法用于处理合并两个Collector - foojay


什么是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