Java 12:Teeing Collector

在本文中,我们将介绍一个在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."
方法签名:

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.*;减少编写的代码量。

嘉宾名单

我们从对象列表(流)中提取两种不同类型的信息。每位客人都必须接受邀请,才能带上家人。
我们想知道谁确认了预订 和参与者总数(包括客人和家庭成员)。

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 }

使用的类

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 +
 ", total number of participants = " + totalNumberOfParticipants +
 " }";
  }}

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

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

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 来返回两个值:

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 类:

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!
点击英文原文链接
更多文章欢迎访问: http://www.apexyun.com
公众号:银河系1号
联系邮箱:public@space-explore.com
(未经同意,请勿转载)

【资源说明】 1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通。 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 本文介绍了基于QEM(Quadric Error Metrics,二次误差度量)的优化网格简化算法的C和C++实现源码及其相关文档。这一算法主要应用于计算机图形学领域,用于优化三维模型的多边形数量,使之在保持原有模型特征的前提下实现简化。简化的目的是为了提高渲染速度,减少计算资源消耗,以及便于网络传输等。 本项目的核心是网格简化算法的实现,而QEM作为该算法的核心,是一种衡量简化误差的数学方法。通过计算每个顶点的二次误差矩阵来评估简化操作的误差,并以此来指导网格简化过程。QEM算法因其高效性和准确性在计算机图形学中广泛应用,尤其在实时渲染和三维打印领域。 项目代码包含C和C++两种语言版本,这意味着它可以在多种开发环境中运行,增加了其适用范围。对于计算机相关专业的学生、教师和行业从业者来说,这个项目提供了丰富的学习和实践机会。无论是作为学习编程的入门材料,还是作为深入研究计算机图形学的项目,该项目都具有实用价值。 此外,项目包含的论文文档为理解网格简化算法提供了理论基础。论文详细介绍了QEM算法的原理、实施步骤以及与其他算法的对比分析。这不仅有助于加深对算法的理解,也为那些希望将算法应用于自己研究领域的人员提供了参考资料。 资源说明文档强调了项目的稳定性和可靠性,并鼓励用户在使用过程中提出问题或建议,以便不断地优化和完善项目。文档还提醒用户注意查看,以获取使用该项目的所有必要信息。 项目的文件名称列表中包含了加水印的论文文档、资源说明文件和实际的项目代码目录,后者位于名为Mesh-Simplification-master的目录下。用户可以将这些资源用于多种教学和研究目的,包括课程设计、毕业设计、项目立项演示等。 这个项目是一个宝贵的资源,它不仅提供了一个成熟的技术实现,而且为进一步的研究和学习提供了坚实的基础。它鼓励用户探索和扩展,以期在计算机图形学领域中取得更深入的研究成果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值