java - Spliterator trySplit 返回类型

标签 java lambda java-8 spliterator

我在 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返回 OptionaltrySplit 等方法返回值或空值。

  • 类似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/

相关文章:

java - 在不同版本的 JRE 上执行 SWING 应用程序时,堆使用情况不同

Java双冒号运算符从编译时到字节码生成?

c++ - 通过非常量引用将使用自动关键字声明的 lambda 作为参数传递给 std::function 参数类型

Java 8 分组并附加到集合

java - 确保字符串不超过给定长度的优雅方法

java - 我不明白这个循环

Java lambda 表达式 : Combinator-Pattern Improvement

python - python 类的 Lambda 函数?

Java 8 - 更新同一流代码中的两个属性

java - Android中如何解析树结构JSON并显示在UI中