Java 为什么Hashmap允许空键?

Java 为什么Hashmap允许空键?,java,collections,hashmap,Java,Collections,Hashmap,实际上,我读了很多关于这个问题的帖子,但没有得到“为什么Hashmap允许空键?”的确切原因/答案。有人能举个例子给我确切的答案吗?对你的问题的一种解释: 为什么hashmap只允许一个空键 问问自己:如果HashMap允许多个null键,map对象如何区分它们 提示:只有一个null值 对你问题的另一种解释 为什么hashmap允许[a]空键 因为它在某些情况下是有用的,并且因为没有真正的语义需要禁止它1,2 相比之下,对于TreeMapnull键是不允许的,因为考虑到涉及null的排序的影

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

对你的问题的一种解释:

为什么hashmap只允许一个空键

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

提示:只有一个
null


对你问题的另一种解释

为什么hashmap允许[a]空键

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

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

  • 假设
    Comparable
    的指定语义是抛出NPE
  • Comparator
    允许排序
    null
    ,但不要求排序。许多常见的实现都没有
因此,如果
TreeMap
允许
null
,那么映射的行为可能会有所不同,这取决于使用的是
比较器还是
可比较的
。乱七八糟的


1-至少,这是1998年他们在Java1.2中指定
HashMap
时的观点。从那时起,一些设计师可能已经改变了主意,但由于明确规定了行为,因此不能在不破坏兼容性的情况下进行更改。这不会发生的


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

Java工程师一定已经意识到,使用空键和值有其用途,就像在默认情况下使用它们一样。所以,他们在Java5中为HashMap类提供了集合框架,能够存储空键和值

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

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


此链接可以回答更多问题,javadoc for HashMap.put明确指出:

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


它清楚地说明了当你使用地图上已有的键进行put时会发生什么。key==null的具体情况的行为方式是相同的:null键不能有两个不同的映射(就像不能有任何其他键一样)。

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

因为他们觉得没有必要禁止它。当你可以从映射中获得默认值时,你可以使用空值键,而没有键。问为什么只有一个容差似乎不是一个合理的问题。我同意,我也不知道上面问题的确切原因。你为什么问这个问题n?您对功能有什么问题?另请参见:和@StephenC如果是这样,那么为什么
CHM
不允许它?我几乎不同意这个答案-因为我听到Stuart Marks说,使用空键的决定现在被视为一个错误,这是一开始就做的。@Eugene See,这引用了JDK的一些发行说明1.2,大概是Joshua Bloch写的,提到空支持是为了与
TreeMap
保持一致(我不理解),这也提到了客户请求(可以理解)。它还链接到Doug Lea的一封电子邮件,他在邮件中解释了CHM的行为,并表示他在非同时收集的问题上与Bloch的意见不一致。然而,…@Eugene In,Bloch说“如果一个API允许空值存在更长的时间,这对你没有任何好处。它只是将异常推送到下一个你将其传递给的API。“我不能代表布洛赫说明他是否改变了主意。不过,当前的JDK团队强烈反对空值,特别是因为未来的值类型很可能不可空值。@StuartMarks这比我想从您那里得到的多得多:)非常感谢!