- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在 java.util.Spliterator
(Java 8) 中偶然发现了一个有趣的细节。
方法 trySplit() 应该返回 Spliterator 的实例或 null
,如果它不能被拆分。 Java 文档说明如下:
* @return a {@code Spliterator} covering some portion of the
* elements, or {@code null} if this spliterator cannot be split.
在我看来,它是使用 java.util.Optional
的完美场所。根据 javadoc:
* A container object which may or may not contain a non-null value.
有什么原因,为什么没有使用 Optional?
谷歌搜索没有太大帮助,除了这个 question在 lambda-dev 邮件列表中,没有得到答复。
最佳答案
之所以会这样,有几个原因。当然,从概念上讲,trySplit
可以返回 Optional<Spliterator<T>>
,但有一些设计力量反对这一点。
一个原因是方法之间存在差异,例如 findFirst
返回 Optional
与 trySplit
等方法返回值或空值。
findFirst
的方法由应用程序代码调用并返回值。trySplit
的方法由库代码调用并返回值。JDK 类库的一个设计方面是库 API 旨在(或应该)使应用程序代码更容易,而库代码通常会变得更复杂,以使应用程序更简单。
Optional
的主要原因之一是为了避免将空值从库传递到应用程序代码,因为不正确的空值处理是 NullPointerException
的常见来源秒。而不是 null
, API 像 findFirst
将返回一个空的 Optional
,它得到了一组丰富的方法的支持,例如 orElse
, map
, filter
, flatMap
等,为应用程序处理未找到的情况提供了很大的灵 active 。
请注意 trySplit
的可空返回值正朝着相反的方向发展:从应用程序到库。
与让应用程序从库接收可为空值相比,让应用程序代码将可空值传递或返回到库对应用程序来说更不容易出错。如果您正在编写应用程序并且 API 指示您应该将 null 传递或返回到库,那么这将不可能在您的代码中生成 NPE。实际上,API 中有很多地方(想到 List.sort(null)
),其中 null
在 API 中具有特定的语义。
trySplit
从库中相对较少的地方调用,库维护者承担了正确处理 null
的负担。在所有这些情况下。
另一个主要考虑因素是性能。拆分是建立并行管道的关键路径。它按顺序执行,然后将工作移交给不同的线程以并行执行。每Amdahl's Law ,为了使并行性尽可能高效,您希望最小化顺序设置开销。
事实是 Optional
是一个盒子,将一个值装箱和拆箱到 Optional
是有成本的。 .在某些情况下,JIT 编译器可能能够优化它,但也可能不会。即使是这样,代码也会在一段时间内运行,但 Optional
还没有被优化掉。这是额外的开销。既然图书馆代码愿意承担处理重担null
正确地,我们可以通过不使用 Optional
来保证没有装箱开销在这种情况下完全没有。
关于java - Spliterator trySplit 返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30194584/
我在想问题的答案:How to test for null keys on any Java map implementation? 我的第一个想法是检查 map 键集的 Spliterator 是否
在 Java 1.8.0_25 发布到荒野之后有一个有趣的情况......我相信我的问题的根源主要与接口(interface)中“默认”实现的新(到 1.8)特性有关。 我正在开发的应用程序目前的目标
我发现 Java 并行流有一些令人惊讶的行为。我自己制作了Spliterator ,并且生成的并行流被分割,直到每个流中只有一个元素。这似乎太小了,我想知道我做错了什么。我希望我可以设置一些特征来纠正
我对我的所有研究感到有点困惑。我有一个名为 TabularResultSet 的自定义界面(为了举例,我已经淡化了它)它遍历任何本质上是表格的数据集。它有一个类似于迭代器的 next() 方法,它可以
我遇到了流的 dropWhile 或 takeWhile 方法的问题,因为 spliterator 正在跳过特定模式奇数或偶数中的文本部分。应该怎样处理文本的所有部分?我的方法在这里: void re
https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html SIZED Characteristic value sign
我正在玩 Java 8 Spliterator并创建了一个将斐波那契数字流式传输到给定的 n。所以对于斐波那契数列 0, 1, 1, 2, 3, 5, 8, ... n fib(n) -----
我想使用 Stream 并行处理一组未知数量的异构远程存储 JSON 文件(文件数量预先未知)。这些文件的大小差异很大,从每个文件 1 个 JSON 记录到某些其他文件中的 100,000 条记录。在
这可能是非常基本的,但我不是 Java 人。这是我的处理代码,它只是打印和 hibernate : private static void myProcessings(int value)
我正在查看 Spliterator 的文档,根据它,Spliterator 不是线程安全的: Despite their obvious utility in parallel algorithms,
我最近发现了一个错误 StreamSupport.intStream(/* a Spliterator.ofInt */, true) .limit(20) 调用 Spliterator.of
我在 java.util.Spliterator (Java 8) 中偶然发现了一个有趣的细节。 方法 trySplit() 应该返回 Spliterator 的实例或 null,如果它不能被拆分。
我明白 there is overhead in setting up并行 Stream 的处理,如果项目很少或每个项目的处理速度很快,则单线程中的处理速度更快。 但是,trySplit() 是否有类
stream.spliterator() 是否隐式关闭了 stream,还是之后需要显式关闭它? Stream stream = Stream.of("a", "b", "c"); Spliterat
在Collection的源代码中,我想知道为什么@Override使用注释。 spliterator()方法不是来自 Iterable ,和Object也没有。 public interface Co
我正在使用 Java 8 流。 当我使用 spliterator 添加到 map 时,出现重复键异常,但使用标准 for 循环不会引发异常。 // This works Map myMap = new
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我读了一些关于如何创建有限的 Stream 的问题( Finite generated Stream in Java - how to create one? , How do streams sto
我将流拆分器直接用于我正在编写的库中的低级操作。最近,当我进行流拆分器和交错 tryAdvance/trySplit 调用时,我发现了非常奇怪的行为。这是演示问题的简单代码: import java.
我注意到使用 Guava 的 Iterables.partition(collection, partitionSize).spliterator() 生成的拆分器表现得很奇怪。 在生成的拆分器上执行
我是一名优秀的程序员,十分优秀!