【问题标题】:Does a sequential stream in Java 8 use the combiner parameter on calling collect?Java 8 中的顺序流在调用 collect 时是否使用组合器参数?
【发布时间】:2014-08-03 20:17:00
【问题描述】:

如果我在顺序流上调用 collect(例如,通过调用 Collection.stream()),那么它会使用我传递给 collect 的组合器参数吗?我想不是,但我在文档中什么也没看到。如果我是正确的,那么不得不提供一些我知道不会被使用的东西(如果我知道它是一个顺序流)似乎很不幸。

【问题讨论】:

  • 当你为组合器传递 null 时会发生什么?你从这个实验中得出什么结论?
  • @JBNizet 会抛出 NullPointerException。

标签: java java-8 java-stream


【解决方案1】:

记住要根据接口规范进行开发,而不是根据实现进行开发。下一个 Java 版本的实现可能会发生变化,而规范应该保持稳定。

规范不区分顺序流和并行流。因此,您应该假设可能会使用 combiner。实际上,有很好的例子表明用于顺序流的 combiners 可以提高性能。例如,以下 reduce 操作连接字符串列表。在没有 combiner 的情况下执行代码具有二次复杂度。使用 combiner 的智能执行可以大大减少运行时间。

List<String> tokens = ...;
String result = tokens.stream().reduce("", String::concat, String::concat);

【讨论】:

  • 如果Stream 实现认识到使用组合器是否可以提高性能,那将是非常智能。然而,更大的风险是,开发者自己一次将流更改为并行,他忘记了省略的组合器……
  • @Holger Right,或其他开发人员将流传递给您的代码,并且该流将来可能会更改为并行。
  • 感谢您的回答。我遇到了同样的问题,虽然一直坚持针对接口开发,但我觉得很遗憾没有没有组合器的收集器的“简单”版本。这会让事情变得容易得多。他们本可以创建一个Collector.Characteristics 来表明这一点,或者更简单的Collector 接口版本...
  • 还有一个问题:Here我找到了A sequential implementation of a reduction using a collector would create a single result container using the supplier function, and invoke the accumulator function once for each input element.这句话,那不是已经表明在这种情况下没有使用combiner吗?
  • @GeekFactory 您忽略了“只是连接它们”的成本。字符串连接意味着创建一个新字符串,它是两个参数字符串的副本。字符串越长,开销越大。并且多个字符串连接的中间结果是一个越来越长的字符串。您可以搜索“Shlemiel the Painter's Algorithm”以获得直观的图片。另请参阅ideone.com/0kRRnt 只是为了清楚起见,collect(joining()) 仍然更好,但我希望您看到,在此示例中使用组合器可以减少开销。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-26
  • 2015-03-04
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多