前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 12:Teeing Collector

Java 12:Teeing Collector

作者头像
银河1号
发布2019-04-12 09:38:51
3580
发布2019-04-12 09:38:51
举报
文章被收录于专栏:银河系资讯银河系资讯

在本文中,我们将介绍一个在Java 12中引入的新集合。这个新功能并未在官方JEP中公布,因为它是一个标题Create Collector的微小更改请求,它合并了其他两个其他collector的结果。

Documentation

点击这里查看Collectors#teeing官方文档。根据文档:

"...returns a Collector that is a composite of two downstream collectors. Every element passed to the resulting collector is processed by both downstream collectors, then their results are merged using the specified merge function into the final result."

方法签名:

代码语言:javascript
复制
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)

有趣的事实

这是一个发球台:

发球的词源可以帮助我们在日常活动中记住这个名字,或者在工作场所展示我们的知识。

Teeing起源于管道三通!根据维基百科的说法,“三通是最常见的管道配件,用于组合(或分割)流体流动。”

Linux具有拆分数据的命令tee。根据作者,我们找到了Richard Stallman。

为此功能提出的其他名称包括:二等分,双工,分叉,复制器,扇出,攻丝,解压缩,收集,扩展,分叉等。

单击此处, 查看Java Core Devs评估的备选列表。

用例示例

我收集了三个不同复杂程度的不同例子。

你可以静态引入import static java.util.stream.Collectors.*;减少编写的代码量。

嘉宾名单

我们从对象列表(流)中提取两种不同类型的信息。每位客人都必须接受邀请,才能带上家人。

我们想知道谁确认了预订参与者总数(包括客人和家庭成员)。

代码语言:javascript
复制
var result =
  Stream.of(
 // Guest(String name, boolean participating, Integer participantsNumber)
 new Guest("Marco", true, 3),
 new Guest("David", false, 2),
 new Guest("Roger",true, 6))
  .collect(Collectors.teeing(
 // first collector, we select only who confirmed the participation
    Collectors.filtering(Guest::isParticipating,
 // whe want to collect only the first name in a list
       Collectors.mapping(o -> o.name, Collectors.toList())),
 // second collector, we want the total number of participants
       Collectors.summingInt(Guest::getParticipantsNumber),
 // we merge the collectors in a new Object,
 // the values are implicitly passed
       EventParticipation::new
   ));
  System.out.println(result);
 // Result
 // EventParticipation { guests = [Marco, Roger],
 // total number of participants = 11 }

使用的类

代码语言:javascript
复制
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;}@Overridepublic String toString() {
 return "EventParticipation { " +
 "guests = " + guestNameList +
 ", total number of participants = " + totalNumberOfParticipants +
 " }";
  }}

过滤两个不同列表中的名称

在此示例中,我们根据过滤器将名称流拆分为两个列表。

代码语言:javascript
复制
var result =
  Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One",
 "Angular Connect")
  .collect(Collectors.teeing(
 // first collector
  Collectors.filtering(n -> n.contains("xx"), Collectors.toList()),
 // second collector
  Collectors.filtering(n -> n.endsWith("One"), Collectors.toList()),
 // merger - automatic type inference doesn't work here
  (List<String> list1, List<String> list2) -> List.of(list1, list2)
  ));
  System.out.println(result); // -> [[Devoxx, Voxxed Days], [Code One, Basel One]]

计算并汇总整数流

也许,你在博客上看到了一个类似的例子,它合并了sum和count平均数。这个例子不需要Teeing,你只需要使用AverageInt和一个简单的收集器。

以下示例使用 Teeing 来返回两个值:

代码语言:javascript
复制
var result =
  Stream.of(5, 12, 19, 21)
    .collect(Collectors.teeing(
 // first collector
      Collectors.counting(),
 // second collector
      Collectors.summingInt(n -> Integer.valueOf(n.toString())),
 // merger: (count, sum) -> new Result(count, sum);
      Result::new
  ));
  System.out.println(result); // -> {count=4, sum=57}

Result 类:

代码语言:javascript
复制
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 +
 '}';
  }}

陷阱

Map.Entry

许多示例用Map.Entry 存储BiFunction的结果。请不要这样做,因为你没有存储 Map。Java Core没有标准对象来存储两个值 - 你必须自己创建它。

Pair 在Apache Utils实现了 Map.Entry,由于这个原因,它不是一个有效的替代方案。

关于Java 12的一切

你可以在本演示文稿中了解有关Java 12的更多信息和有趣的事实。

Happy collecting!

(未经同意,请勿转载)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 银河系1号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Documentation
  • 有趣的事实
  • 用例示例
    • 嘉宾名单
      • 使用的类
        • 过滤两个不同列表中的名称
          • 计算并汇总整数流
          • 陷阱
            • Map.Entry
            • 关于Java 12的一切
            相关产品与服务
            对象存储
            对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档