EnumSet.spliterator 没有特征 Spliterator.NONNULL
EnumSet.spliterator without characteristic Spliterator.NONNULL
我在想问题的答案:
我的第一个想法是检查地图键集的 Spliterator
是否具有特征 Spliterator.NONNULL
:
map.keySet().spliterator().hasCharacteristics(Spliterator.NONNULL)
JavaDoc 说:
Characteristic value signifying that the source guarantees that
encountered elements will not be null. (This applies, for example, to
most concurrent collections, queues, and maps.)
在回答之前我做了一些检查:
没有提供Compararator
的TreeMap
的Spliterator
没有这个特性,即使自然排序不允许null -键。
new TreeMap<>().keySet().spliterator().hasCharacteristics(Spliterator.NONNULL); // false
更令人惊讶的是 EnumMap
键集的 Spliterator
和 EnumSet
本身不具有此特性。
EnumSet.allOf(DayOfWeek.class).spliterator().hasCharacteristics(Spliterator.NONNULL); // false
我理解 spliterator().hasCharacteristics(Spliterator.NONNULL)
在上述情况下的结果 returns false
作为 Set.spliterator()
的默认实现被评估。
但是这些集合的拆分器没有覆盖 Set.spliterator()
来创建 Spliterator
和 Spliterator.NONNULL
的原因吗?这会破坏我不知道的规范吗?
更糟糕的是:
System.out.println(Set.of(1)
.spliterator()
.hasCharacteristics(Spliterator.NONNULL)); // false
即使这些 Set::of
方法记录为:
throws NullPointerException if the element is null
因此无法在 Set
中以 null 结尾。我想真正的答案是尚未完成。
编辑
见
But is there a reason why the spliterators of these sets do not override Set.spliterator()
to create a Spliterator
with Spliterator.NONNULL
?
我们只能推测,但可以肯定的是,某些使用 Comparator
进行排序的 TreeMap
实例确实容纳了空键,因此它们的键集的拆分器一定没有特征Spliterator.NONNULL
。虽然使用其键的自然顺序的 TreeMap
确实不能容纳空键,但我个人并不认为 TreeMap
的键集不使用它来进行区分感到惊讶。我希望这种 属性 完全由所涉及的 类 驱动,而不是由每个实例的详细信息驱动。
Would this break a specification I am not aware of?
也许吧。 The docs for Set.spliterator()
指定
The Spliterator
reports Spliterator.DISTINCT
. Implementations should document the reporting of additional characteristic values.
(强调已添加。)The docs for TreeMap.keySet() 说
The set's spliterator is late-binding, fail-fast, and additionally
reports Spliterator.SORTED
and Spliterator.ORDERED
with an encounter
order that is ascending key order. The spliterator's comparator (see
Spliterator.getComparator()
) is null
if the tree map's comparator (see
SortedMap.comparator()
) is null
. Otherwise, the spliterator's
comparator is the same as or imposes the same total ordering as the
tree map's comparator.
请注意,此集合的文档符合 Set.spliterator()
文档中的期望集,没有指定,甚至有条件地指定 Spliterator.NONNULL
是键集的拆分器将报告的特征之一。进一步注意,那些相同的文档 do 描述了这些集合的其他特征,这些特征根据地图的顺序是否基于比较器而有所不同。
因此,不,您不应该期望 TreeMap
键集',拆分器在任何情况下都有报告 Spliterator.NONNULL
。我无法明确说明做出此选择的原因,但它符合我对 Java 设计理念的看法。
你也写了,
Even more suprising was the fact that Spliterator
s of an EnumMap
keyset and of EnumSet
itself do not have this characteristic.
我同意这些分裂者可以合理地报告 Spliterator.NONNULL
。我不知道为什么他们选择不这样做,除非这只是一个疏忽。尽管如此,我观察到他们的文档确实没有指定这些拆分器将报告 Spliterator.NONNULL
。在这种情况下,可以预料那些拆分器不会报告该特性。
我在想问题的答案:
我的第一个想法是检查地图键集的 Spliterator
是否具有特征 Spliterator.NONNULL
:
map.keySet().spliterator().hasCharacteristics(Spliterator.NONNULL)
JavaDoc 说:
Characteristic value signifying that the source guarantees that encountered elements will not be null. (This applies, for example, to most concurrent collections, queues, and maps.)
在回答之前我做了一些检查:
没有提供Compararator
的TreeMap
的Spliterator
没有这个特性,即使自然排序不允许null -键。
new TreeMap<>().keySet().spliterator().hasCharacteristics(Spliterator.NONNULL); // false
更令人惊讶的是 EnumMap
键集的 Spliterator
和 EnumSet
本身不具有此特性。
EnumSet.allOf(DayOfWeek.class).spliterator().hasCharacteristics(Spliterator.NONNULL); // false
我理解 spliterator().hasCharacteristics(Spliterator.NONNULL)
在上述情况下的结果 returns false
作为 Set.spliterator()
的默认实现被评估。
但是这些集合的拆分器没有覆盖 Set.spliterator()
来创建 Spliterator
和 Spliterator.NONNULL
的原因吗?这会破坏我不知道的规范吗?
更糟糕的是:
System.out.println(Set.of(1)
.spliterator()
.hasCharacteristics(Spliterator.NONNULL)); // false
即使这些 Set::of
方法记录为:
throws NullPointerException if the element is null
因此无法在 Set
中以 null 结尾。我想真正的答案是尚未完成。
编辑
见
But is there a reason why the spliterators of these sets do not override
Set.spliterator()
to create aSpliterator
withSpliterator.NONNULL
?
我们只能推测,但可以肯定的是,某些使用 Comparator
进行排序的 TreeMap
实例确实容纳了空键,因此它们的键集的拆分器一定没有特征Spliterator.NONNULL
。虽然使用其键的自然顺序的 TreeMap
确实不能容纳空键,但我个人并不认为 TreeMap
的键集不使用它来进行区分感到惊讶。我希望这种 属性 完全由所涉及的 类 驱动,而不是由每个实例的详细信息驱动。
Would this break a specification I am not aware of?
也许吧。 The docs for Set.spliterator()
指定
The
Spliterator
reportsSpliterator.DISTINCT
. Implementations should document the reporting of additional characteristic values.
(强调已添加。)The docs for TreeMap.keySet() 说
The set's spliterator is late-binding, fail-fast, and additionally reports
Spliterator.SORTED
andSpliterator.ORDERED
with an encounter order that is ascending key order. The spliterator's comparator (seeSpliterator.getComparator()
) isnull
if the tree map's comparator (seeSortedMap.comparator()
) isnull
. Otherwise, the spliterator's comparator is the same as or imposes the same total ordering as the tree map's comparator.
请注意,此集合的文档符合 Set.spliterator()
文档中的期望集,没有指定,甚至有条件地指定 Spliterator.NONNULL
是键集的拆分器将报告的特征之一。进一步注意,那些相同的文档 do 描述了这些集合的其他特征,这些特征根据地图的顺序是否基于比较器而有所不同。
因此,不,您不应该期望 TreeMap
键集',拆分器在任何情况下都有报告 Spliterator.NONNULL
。我无法明确说明做出此选择的原因,但它符合我对 Java 设计理念的看法。
你也写了,
Even more suprising was the fact that
Spliterator
s of anEnumMap
keyset and ofEnumSet
itself do not have this characteristic.
我同意这些分裂者可以合理地报告 Spliterator.NONNULL
。我不知道为什么他们选择不这样做,除非这只是一个疏忽。尽管如此,我观察到他们的文档确实没有指定这些拆分器将报告 Spliterator.NONNULL
。在这种情况下,可以预料那些拆分器不会报告该特性。