【问题标题】:Why does Hashmap allow a null key?为什么 Hashmap 允许空键?
【发布时间】:2023-03-16 05:06:02
【问题描述】:

实际上我阅读了很多关于这个问题的帖子,但没有得到“为什么 Hashmap 允许空键?”的确切原因/答案。请问谁能给我一个例子的确切答案?

【问题讨论】:

  • 因为他们觉得没有必要禁止它。
  • 在没有键的情况下可以从映射中获取默认值时可以使用空键。问为什么只允许一个似乎不是一个合理的问题。
  • 我同意,我也没有得到上述问题的确切原因。你为什么问这个问题?您对功能有什么问题?

标签: java collections hashmap


【解决方案1】:

您的问题的一种解释:

为什么 hashmap [仅] 允许一个空键?

问问自己:如果 HashMap 允许多个 null 键,映射对象将如何区分它们?

提示:null 值只有一个。


您问题的另一种解释

为什么 hashmap 允许 [a] 空键?

因为它在某些情况下很有用,并且因为没有真正的语义需要禁止它1, 2。

相比之下,TreeMap null 键是不允许的,因为考虑到涉及null 的排序的含义,支持它们会很困难。

  • 鉴于 Comparable 的指定语义是抛出 NPE。
  • 允许Comparator 订购null,但这不是必须的。而许多常见的实现却没有。

因此,如果null 允许与TreeMap 一起使用,则映射的行为可能会有所不同,具体取决于使用Comparator 还是Comparable。凌乱。


1 - 至少,这是他们早在 1998 年在 Java 1.2 中指定 HashMap 时的视图。一些设计者可能从那时起改变了主意,但由于行为是 明确指定的 在不破坏兼容性的情况下无法更改它。它不会发生...

2 - 支持null 键需要HashMap 中的一些特殊情况代码,这至少增加了实现的复杂性。尚不清楚这是否是 HashMap 的性能开销,因为即使不允许使用 null 键,仍需要对 null 键进行隐式测试。这很可能是噪音。

【讨论】:

  • @StephenC 如果是这样,那为什么CHM 不允许呢?我几乎不同意这个答案 - 因为我听过 Stuart Marks 说过,现在将决定使用 null 键视为最初的错误。
  • @Eugene See this answer,引用了 JDK 1.2 的一些发行说明,大概由 Joshua Bloch 编写,提到 null 支持是为了与 TreeMap 保持一致(我不明白)并且还提到了客户的要求(这是可以理解的)。它还链接到来自 Doug Lea 的电子邮件消息,其中他解释了 CHM 的行为,并表示他在非并发集合的问题上不同意 Bloch。然而……
  • @Eugene 在this interview 中,Bloch 说“如果 API 允许空值存在更长时间,这对您没有任何帮助。它只是将异常推到您传递的下一个 API的事情。”我不能代表布洛赫谈论他是否改变了主意。但是,当前的 JDK 团队强烈反对空值,特别是因为未来的值类型很可能不能为空。
  • @StuartMarks 这比我想从你那里得到的要多得多 :) 非常感谢!
【解决方案2】:

Java 工程师一定已经意识到,拥有 null 键和值的用途就像在默认情况下使用它们一样。因此,他们在 Java 5 中提供了带有集合框架的 HashMap 类,具有存储空键和值的能力。

在HashMap中插入键值对的put方法检查空键并将其存储在内部表数组的第一个位置。它不怕 null 值,也不会像 Hashtable 那样抛出 NullPointerException。

现在,只能有一个空键,因为键必须是唯一的,尽管我们可以有多个空值与不同的键关联。

此链接可以回答更多hashmap null key explained

【讨论】:

    【解决方案3】:

    HashMap.put 的 javadoc 明确指出:

    将指定的值与此映射中的指定键相关联。如果映射先前包含键的映射,则替换旧值。

    它清楚地说明了当您使用地图中已经存在的键执行 put 时会发生什么。 key == null 的特定情况的行为方式相同:您不能对 null 键有两个不同的映射(就像您不能对任何其他键一样)。

    【讨论】:

      【解决方案4】:

      这仍然被视为HashMap 的早期实现中的一个错误,不幸的是人们在哪里(在?)依赖(以及在 java-8 之前的某些特定顺序)。问题是,拥有这个null 密钥,您始终可以“免费”传递一些元数据以及您的实际数据。请注意,所有新集合 ConcurrentHashMap、Map.of(在 java-9 中)等 - 都禁止以空值开头。

      【讨论】:

        猜你喜欢
        • 2018-07-19
        • 2012-08-12
        • 1970-01-01
        • 1970-01-01
        • 2021-12-30
        • 2023-03-11
        • 2016-06-15
        • 2012-01-09
        • 1970-01-01
        相关资源
        最近更新 更多