Java 12 Teeing Collector


前言:

     Collectors#teeing :返回一个由两个下游收集器组成的收集器。传递给生成的收集器的每个元素都由下游收集器处理,然后使用指定的合并函数将它们的结果合并到最终结果中。

简单地说,它允许使用两个独立的收集器收集流,然后使用提供的双功能合并结果。

//方法相应参数 函数等。
static <T, R1, R2, R> Collector<T, ?, R> teeing (Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger)

举几个栗子:

//vo
class Guest {
  private String name; //姓名
  private boolean participating;//是否参加
  private Integer participantsNumber; //参与人数

  public Guest(String name, boolean participating,
   Integer participantsNumber) {
    this.name = name;
    this.participating = participating;
    this.participantsNumber = participantsNumber;
  }
  public boolean isParticipating() {
    return participating;
  }
  public Integer getParticipantsNumber() {
    return participantsNumber;
  }
}
class EventParticipation {
  private List<String> guestNameList;
  private Integer totalNumberOfParticipants;
  public EventParticipation(List<String> guestNameList,
   Integer totalNumberOfParticipants) {
    this.guestNameList = guestNameList;
    this.totalNumberOfParticipants = totalNumberOfParticipants;
}
@Override
public String toString() {
  return "EventParticipation { " +
    "guests = " + guestNameList +
    ", 总参与人数 = " + totalNumberOfParticipants +
    " }";
  }}

1.统计成功参加的和总人数:

import static java.util.stream.Collectors.*;

var result =
  Stream.of(
  // Guest(String name, boolean participating, Integer participantsNumber)
  new Guest("张三", true, 3),
  new Guest("李四", false, 2),
  new Guest("王五",true, 6))
  .collect(Collectors.teeing(
    // 第一个收集器,统计确认参加的
    Collectors.filtering(Guest::isParticipating,
       //只收集列表中名字的参与者
       Collectors.mapping(o -> o.name, Collectors.toList())),
       // 第二个收集器,我们需要参与者总数
       Collectors.summingInt(Guest::getParticipantsNumber),
       //收集器合并到一个新对象中, 值是隐式传递的
       EventParticipation::new
   ));
  System.out.println(result);

  // 打印结果
  // EventParticipation { guests = [张三, 李四],
  // 总参加人数 = 11 }

2.筛选两个不同Lists中名称:

//根据过滤器将名称流拆分为两个列表
var result =
  Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One","Angular Connect")
  .collect(Collectors.teeing(
  // 第一个收集器 过滤包含 xx
  Collectors.filtering(n -> n.contains("xx"), Collectors.toList()),
  // 第二个收集器 过滤One结尾的
  Collectors.filtering(n -> n.endsWith("One"), Collectors.toList()),
  // 合并
  (List<String> list1, List<String> list2) -> List.of(list1, list2)
  ));
  //执行结果
  System.out.println(result); // -> [[Devoxx, Voxxed Days], [Code One, Basel One]]

3.计算并汇总

var result =
  Stream.of(5, 12, 19, 21)
    .collect(Collectors.teeing(
      // 第一个收集器
      Collectors.counting(),
      // 第二个收集器 求和
      Collectors.summingInt(n -> Integer.valueOf(n.toString())),
      // 合并输出一个新的对象: (count, sum) -> new Result(count, sum);
      Result::new
  ));
  //执行结果
  System.out.println(result); // -> {count=4, sum=57}




class Result {
  private Long count;
  private Integer sum;

  public Result(Long count, Integer sum) {
    this.count = count;
    this.sum = sum;
  }
  @Override
  public String toString() {
    return "{" +
      "count=" + count +
      ", sum=" + sum +
    '}';
  }}

  Stream Api#teeing()更多参考https://dzone.com/articles/java-12-the-teeing-collector


 

上一篇:PAT甲级——1121 Damn Single (C++的各种stl的使用)


下一篇:django数据迁移命令