当前位置: 首页 > 知识库问答 >
问题:

枚举集。没有特征拆分器的拆分器。非空

林华皓
2023-03-14

我在思考这个问题的答案:如何在任何Java映射实现上测试空键?

我的第一个想法是检查映射的键集的Spliterator是否具有特征Spliterator.NONNULL

map.keySet().spliterator().hasCharacteristics(Spliterator.NONNULL)

JavaDoc说:

表示源保证遇到的元素不为空的特征值。(例如,这适用于大多数并发集合、队列和映射。)

在回答之前,我做了一些检查:

即使自然排序不允许空键,没有提供比较器TreeMapSpliterator也没有此特性。

new TreeMap<>().keySet().spliterator().hasCharacteristics(Spliterator.NONNULL); // false 

更令人惊讶的是,EnumMap键集的拆分器s和Enum集本身不具有此特性。

EnumSet.allOf(DayOfWeek.class).spliterator().hasCharacteristics(Spliterator.NONNULL); // false

我知道< code>spliterator()的结果。has characters(Spliterator。NONNULL)在计算< code>Set.spliterator()的默认实现时返回< code>false。

但是,这些集合的拆分器没有覆盖Set.spliterator()以创建具有Spliterator.NONNULL拆分器有什么原因吗?这会破坏我不知道的规范吗?

共有2个答案

松雅昶
2023-03-14

但是,这些集合的拆分器不覆盖<code>集合有什么原因吗。spliterator()创建一个<code>spliterator?

我们只能推测,但可以肯定的是,一些使用比较器s进行排序的TreeMap实例确实容纳了空键,因此它们的键集的拆分器不能具有特征性的Spliterator.NONNULL。虽然使用其键的自然排序的TreeMap确实无法容纳空键,但我个人并不觉得TreeMap的键集不使用它来区分并不奇怪。我希望这种属性完全由所涉及的类驱动,而不是由每个实例的详细信息驱动。

这会违反我不知道的规范吗?

也许。Set.spliterator() 的文档指定

Spliterator 报告 Spliterator.DISTINCT。实现应记录其他特征值的报告。

(增加强调)TreeMap的文档。keySet()说

该集合的拆分器是后期绑定的、故障快速的,并且另外报告< code >拆分器。排序和< code >分隔符。ORDERED,遇到顺序为升序。如果树映射的比较器(参见< code > sorted map . comparator())为< code>null,则拆分器的比较器(参见< code > spliterator . get comparator())为< code>null。否则,spliterator的比较器与树映射的比较器相同,或者采用相同的总排序。

请注意,此集合的文档符合Set.spliterator()文档中的期望集,即使没有指定Spliterator.NONNULL是键集拆分器将报告的特征之一。进一步注意,这些相同的文档确实描述了这些集合的其他特征,这些特征取决于映射的顺序是否基于比较器。

因此,不,您不应该期望TreeMapkey set',拆分器在任何情况下都有报告Spliterator.NONNULL。我不能肯定地说为什么做出这个选择,但它符合我对Java设计理念的看法。

你还写道,

更令人惊讶的是,EnumMap键集的拆分器s和Enum集本身不具有此特性。

我同意这些拆分器可以合理地报告Spliterator.NONNULL。我不知道为什么选择他们不会这样做,除非这只是一个疏忽。尽管如此,我观察到他们的文档确实没有指定这些拆分器将报告Spliterator.NONNULL。既然如此,可以预期这些拆分器不会报告该特性。

贺聪
2023-03-14

更糟糕的是:

System.out.println(Set.of(1)
             .spliterator()
             .hasCharacteristics(Spliterator.NONNULL)); // false

即使这些< code>Set::of方法被记录为:

如果元素为空,则抛出NullPointerException

因此,无法在<code>集合

编辑

请参阅斯图尔特·马克斯对此的评论

 类似资料:
  • 目前,我正在与spring integration合作开发新的应用程序,并启动了poc,以了解如何处理故障案例。在我的应用程序中,spring integration将接收来自IBM mq的消息,并根据消息类型验证头信息和到不同队列的路由。传入的消息可能是批量消息,所以我使用了spring integration的拆分器和聚合器,并且对技术工作流程有很好的进展和控制。目前我面临的问题很少,我们有I

  • 我正在为C 11编写一个类似于boost::promote的升级模板别名。这样做的目的是在从变量函数检索参数时避免出现警告。例如 提升模板别名提升了变量参数的默认参数提升后的类型: 1)小于int的整数提升为int 2)浮点提升为双 我的问题是,可以提升标准C枚举,但不能提升C 11枚举类(编译器不会生成警告)。我希望升级使用常规枚举,但忽略C 11枚举类。 如何区分枚举类和枚举在我的推广模板别名

  • 使用Spring Integr中的拆分器,我拆分了从数据库中的表中选择的数据行。每条消息完成处理后,我想像旧消息一样将每条消息聚合到一条消息中。我该怎么办?我不知道拆分器拆分了多少条消息。我只知道拆分消息头中的相关ID。即使我聚合消息,我也无法制定发布策略。 我如何解决这个问题? 以及是否有任何方法可以使用jdbc-out站网关或jdbc-out站通道适配器一次插入多行数据,而无需使用拆分器插入每

  • 在机器学习中,通常将所有的数据划分为三份:训练数据集、验证数据集和测试数据集。它们的功能分别为 训练数据集(train dataset):用来构建机器学习模型 验证数据集(validation dataset):辅助构建模型,用于在构建过程中评估模型,为模型提供无偏估计,进而调整模型超参数 测试数据集(test dataset):用来评估训练好的最终模型的性能 不断使用测试集和验证集会使其逐渐失去

  • 我正在开发一个Spring集成应用程序。 我有一个入站通道适配器,用于读取目录,然后是一个拆分器,用于将文件拆分为行,最后是一个udp出站通道适配器,用于发送行 我想每秒钟发一封信 我可以通过定义自己的拆分器并在每次读取一行时等待1s来做到这一点,但我想知道是否可以在xml文件中尽可能简单地完成它。 提前谢谢