【发布时间】:2016-08-22 11:03:48
【问题描述】:
我想找出一个与 Java 8 Stream 等效的简单实现,它可以让我探索延迟计算的查询算法的开发(例如 map()、filter()、reduce() 等)。 注意:实现比 Stream 更好的解决方案不是我的目标。另一方面,我唯一的目标是了解 Stream 内部结构。
然而,我发现的每个实现都是基于Iterable<T>,例如以下答案中提出的解决方案:
- How are lazy streams implemented in Java 8?
- streaming is not a container of data, but a container of logic
- Java8 internal iteration
然而,我对这些解决方案中的任何一个都不满意,因为:
- 它们太冗长了。
- 它们对于新的查询方法不灵活。包含新的查询方法需要对结构进行修改。
- 尽管有查询参数,但它们并没有利用 Java 8 的新特性,例如:第一类函数或默认方法。
- 他们都没有使用在
Stream<T>上使用的Spliterator<T>方法。
我知道Spliterator<T> 旨在允许分区和并行处理,但我认为它独特的迭代器方法 (boolean tryAdvance(Consumer<t>)) 可以被利用来替代上面列出的那些方法。而且作为stated by Brian Goetz:
Spliterator是更好的Iterator,即使没有并行性。 (它们通常也更容易编写,更难出错。)
那么,是否可以基于Stream<T> 的相同原理(并行处理部分除外)开发一个更易读、更简单、更简洁、更灵活的查询 API 实现?
如果是,你怎么做?我希望看到比上面列出的那些更简单的实现,并尽可能利用新的 Java 8 功能。
要求:
- 不要重用 Java 8 API 中的现有方法
- 并行处理功能超出了本问题的范围。
- 如果可能,最好不要使用
Iterable<T>方法。
我的问题的原因是什么?我认为学习查询 API(如 Stream)的最佳方法是尝试自己实现这些相同的方法。我在学习.net Linq的时候已经成功了。当然,我没有实现比 Linq 更好的实现,但这有助于我理解内部部分。因此,我正在尝试遵循相同的方法来学习 Stream。
这并不罕见。有许多针对其他技术的研讨会遵循这种方法,例如functional-javascript-workshop,大多数练习要求实现现有方法,例如:map()、filter()、reduce()、call()、bind()等等……
选择答案:现在我认为Miguel Gamboa’s answer 是我的选择,而不是Tagir Valeev’s answer,因为后者不允许在不完全遍历整个元素的情况下实现findAny() 或findFirst()通过dataSrc 的forEach()。但是,我认为Tagir Valeev’s answer 在一些中间操作的简洁实现以及性能方面还有其他优点,因为基于forEach() 的方法减少了调解访问数据结构内部的迭代代码的开销,如Brian Goetz on point 2 of its answer
【问题讨论】:
-
如果是为了学习,何不自己尝试一下呢?在运行中实现
Spliterator将map或filter另一个Spliterator的每个项目应该很容易。我不认为重新实现 API 是学习它的最佳方式,但如果你这么认为,那就继续吧…… -
@Holger
Spliterator<T>有 4 个抽象方法,实现起来看起来更痛苦。但是Miguel Gamboa’s answer 提出了一种利用tryAdvance的好方法,它只用一条指令实现了map()和forEach()。关于我的方法,这并不新鲜或不寻常。你知道像functional-javascript-workshop这样的研讨会吗?大多数练习要求实现现有方法,例如:map()、filter()、reduce()、call()、bind()等…… -
@Gaspium:
AbstractSpliterator有恰好一个抽象方法,即相关的tryAdvance。由于这与 Miguel Gamboa 的答案完全相同,因此在复杂性上应该没有区别。除了您不需要实现forEach,因为已经有免费的Spliterator.forEachRemaining。 -
@Holger
AbstractSpliterator是一个类,因此我认为你不能使用 Miguel Gamboa 提出的相同技术,它只返回一个 lambda。 -
@Gaspium:我从来没有说过我对其他问题的答案很满意,我宁愿质疑这些问题关于 SO 范围的有效性。同样,如前所述,如果您真的想学习一些东西,我认为您应该自己尝试一下。
标签: collections lambda java-8 java-stream higher-order-functions