OptionalInt与Optional<Integer>的区别

58
在查看 Java 语言的 java.util 包文档时,我惊讶地发现 Optional<T>OptionalInt 这两个类没有任何关系。这似乎很难相信,因为它表明它们是不相关的类。
  1. 为什么它们没有共同的接口、类或子类型等等,以展示它们之间的关系?(当你查看它们的用法时,它们是非常相似的类。)
  2. 此外,为什么需要一种额外的 OptionalInt 类?为什么不能只使用 Optional<Integer> ?我认为这是由于 int 是一个原始数据类型,但是没有 OptionalChar 类,因此那将不是一个一致的设计选择。
3个回答

44

Java 8引入了很多关于基本类型的专用功能。原因很可能是装箱基本类型会创建很多浪费的“盒子”。

例如,这个:

OptionalInt optionalFirst = IntStream
    .range(0, 100)
    .filter(i -> i % 23 > 7)
    .findFirst();

在这里,返回一个 Optional<Integer> 将是不一致的。而且像 ifPresent(IntConsumer consumer) 这样的方法允许保持在 IntStream 的领域内。 Optional<Integer> 会强制你进行转换(如果您愿意,可以轻松完成)。

没有必要为 charshortbyte 提供特殊支持,因为它们都可以被表示为 int。缺少的是 boolean,但在流中使用它们并没有太多用处,因为只有两个值。


15

为了让Java 8的流更加一致,需要一个OptionalInt类。如果你查看Stream,你会发现许多方法返回Optional<T>类型。但是,处理Stream<Integer>Stream<Long>或任何其他原始流是很繁琐的,因此有了一个IntStream类和一个LongStream类,这些类将对象替换为其未装箱值。例如,查找Stream<Integer>元素的总和不是易事,而对于IntStream,只需调用IntStream#sum即可。

在这些类中,JDK很贴心地将Optional<T>替换为OptionalIntOptionalLong等。


4

OptionalInt 是一个包含原始类型 int 值的容器。原始类型不能作为泛型类的类型参数,因此它无法是 Optional<T> 的子类。


1
那么为什么没有OptionalChar呢? - Michael
zapl 在问题评论中回答了这个问题。 - Jiri Tousek
我不太明白为什么 Optional<Integer> 不足够。你能举个例子吗? - Michael
2
@Michael 因为有时你不想承担自动装箱原语的开销成本。从逻辑上讲,你是正确的,它们本来就是多余的。他们只为最常用的类型做了这个操作,因为他们不想添加太多的类。IntConsumerDoubleConsumer 也是一样,但没有 CharConsumer。请注意,在 Java 9 中,您应该(计划可能会更改)能够对原语进行通用,并且所有这些都将成为遗留问题。 - Sled

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接