为什么在哈希映射中使用空值或空键是有用的?

sab*_*sab 29 java hashmap

Hashtable不允许空键或值,同时HashMap允许空值和1空键.

问题:

  1. 为什么会这样?
  2. 在HashMap中使用这样的键和值有什么用?

Mar*_*ers 44

1.为什么会这样?

HashMap比Hashtable更新并修复了它的一些限制.

我只能猜测设计师的想法,但这是我的猜测:

  • Hashtable通过调用每个键来计算每个键的哈希值hashCode.如果密钥为空,这将失败,因此这可能是禁止空值作为键的原因.
  • Hashtable.get如果密钥不存在,则该方法返回null.如果null是一个有效值,那么null是否意味着密钥存在但值为null,或者密钥是否不存在则不明确.歧义是不好的,所以这可能是禁止空值作为值的原因.

然而事实证明,有时你确实想要存储空值,因此在HashMap中删除了限制.以下警告也包含在以下文档中HashMap.get:

返回值null不一定表示映射不包含键的映射; 地图也可能显式地将键映射为null.


2.在HashMap中使用这样的键和值有什么用?

显式存储null以区分您知道存在但没有关联值的键和不存在的键很有用.一个例子是注册用户及其生日的列表.如果您要求特定用户的生日,您希望能够区分不存在的用户和现有用户,但他们尚未进入他们的生日.

我想不出任何(好)的理由希望存储空作为重点,一般我会建议不要使用空作为重点,但据推测至少有一个人的地方,需要一个键可以为空值.

  • 假设你在计算披萨价格.可以使用地图在顶部和额外成本之间进行映射; 你可以将null映射到零,并且逻辑比你特殊情况下的无顶披萨更简单.它当然不是一个很好的例子,但我认为这表明了一个有效的理由. (10认同)

sin*_*pop 14

嗯,我认为马克·拜尔斯完美的回答,所以只是一个简单的例子,其中空值和键可以是有用的:

想象一下,你有一个昂贵的函数,它总是为相同的输入返回相同的结果.地图是缓存其结果的简单方法.也许有时函数会返回null,但无论如何你都需要保存它,因为执行起来很昂贵.因此,必须存储空值.如果它是函数的可接受输入,则同样适用于null键.


shu*_*lik 6

HashTable 是一个非常古老的类,来自 JDK 1.0。JDK 1.0中的类称为类,默认情况下它们是同步的

\n\n

要理解这一点,首先您需要理解作者在该类上编写的注释。\n\xe2\x80\x9c该类实现了一个哈希表,它将键映射到值。任何非空对象都可以用作键或值。要成功地在哈希表中存储和检索对象,用作键的对象必须实现 hashCode 方法和 equals 方法。\xe2\x80\x9d

\n\n

HashTable类是在哈希机制上实现的,意味着存储任何键值对,其键对象所需的哈希码。HashTable 通过对每个键调用 hashCode 来计算每个键的哈希值。如果 key 为 null ,它将无法为 null key 提供哈希,这将失败,它将抛出NullPointerException,类似的情况也是 value ,如果 value 为 null ,则抛出 null

\n\n

但后来人们意识到空键和空值有其自身的重要性,然后引入了 HashTable 的修订实现,例如 HashMap,允许一个空键和多个空值。

\n\n

对于 HashMap,它允许有一个 null 键,并且对键进行 null 检查,如果键为 null,则该元素将存储在 Entry 数组中的零位置。

\n\n

HashMap 中不能有多个 Null 键,因为键是唯一的,因此只能有一个 Null 键,并且允许有多个 Null 值。

\n\n

USE - 我们可以将空键用于某些默认值。

\n\n

HashTable 的修改和更好的实现后来被引入为ConcurrentHashMap

\n