【问题标题】:What's the difference between Stream.map(...) and Collectors.mapping(...)?Stream.map(...) 和 Collectors.mapping(...) 有什么区别?
【发布时间】:2016-04-21 10:06:26
【问题描述】:

我注意到Stream 中公开的许多功能显然在Collectors 中重复,例如Stream.map(Foo::bar)Collectors.mapping(Foo::bar, ...),或Stream.count()Collectors.counting()。这些方法有什么区别?有性能差异吗?它们的实现方式是否不同,会影响它们的并行化程度?

【问题讨论】:

  • 收集器在用作另一个收集器的下游操作时很有用。例如groupingBy 采用下游收集器收集映射到同一键的所有元素。你不能在那里使用 Stream 操作。
  • 有趣的是,所有采用下游收集器的收集器都有动名词,以-ing结尾
  • @Tunaki 这如何使相同的方法不同。例如stream.collect(Collectors.counting())stream.count()stream.collect(Collectors.mapping(Foo::bar), anotherCollector)stream.map(Foo::bar).collect(anotherCollector)。好像有点多余。
  • 确实collect(Collectors.counting()) 没有优势,但它作为下游收集器确实派上用场,例如collect(partitioningBy(String::isEmpty), Collectors.counting()) 将结果分成 2 个计数而不是 2 个列表

标签: java java-8 java-stream


【解决方案1】:

似乎与Stream 中的功能重复的收集器存在,因此它们可以用作groupingBy() 等收集器组合器的下游收集器

作为一个具体示例,假设您要计算“卖家的交易计数”。你可以这样做:

Map<Seller, Long> salesBySeller = 
    txns.stream()
        .collect(groupingBy(Txn::getSeller, counting()));

如果没有像counting()mapping() 这样的收集器,这类查询会更加困难。

【讨论】:

  • 值得注意的是,Java 9 也会将 filteringflatMapping 添加到 Collectors,因此会有一个收敛......
【解决方案2】:

有很大的不同。流操作可以分为两组:

  • 中间操作 - Stream.mapStream.flatMapStream.filter。那些产生 Stream 的实例并且总是 lazy,例如没有实际遍历 Stream 元素。这些操作用于创建转换链
  • 终端操作 - Stream.collectStream.findFirstStream.reduce 等。这些执行实际工作,例如对流执行转换链操作,产生一个终端值。可以是列表、元素计数、第一个元素等。

查看Stream package summary javadoc 了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 2010-10-02
    • 2011-12-12
    • 2010-09-16
    • 2012-03-14
    • 2012-02-06
    • 2011-02-25
    • 2011-11-22
    相关资源
    最近更新 更多