繁体   English   中英

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

[英]Why is it useful to have null values or null keys in hash maps?

Hashtable不允许空键或值,而HashMap允许空值和1空键。

问题:

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

1.为什么会这样?

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

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

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

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

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


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

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

我想不出任何(好的)理由想要将null存储为键,一般来说我建议不要使用null作为键,但可能至少有一个人需要那些键可以是空值。

好吧,我认为Mark Byers回答得非常好,所以只是一个简单的例子,其中null值和键可能很有用:

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

JDK 1.0开始 ,HashTable是非常老的类。从JDK 1.0到位的类称为Legacy类,默认情况下它们是同步的

要理解这一点,首先你需要了解作者在这个课上写的评论。 “这个类实现了一个哈希表,它将键映射到值。 任何非null对象都可以用作键或值。 要成功存储和检索哈希表中的对象,用作键的对象必须实现hashCode方法和equals方法。“

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

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

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

我们在HashMap中不能有多个Null键,因为Keys是唯一的,因此只允许一个Null键和许多Null值。

USE - 我们可以使用Null键作为一些默认值。

后来,作为ConcurrentHashMap引入了HashTable的修改和更好的实现。

除了Mark Ba​​yers所回答的问题之外,Null被视为数据,必须将其存储为值以便进一步检查。 在许多情况下,null as value可用于检查密钥条目是否存在但没有为其分配值,因此可以采取相应的操作。 这可以通过首先检查密钥是否存在,然后获取值来完成。 还有一个案例,其中只是放入任何数据(没有任何检查)。 获得后,所有检查都会应用到它。

虽然null作为键,但我认为可以用来定义一些默认数据。 通常null作为键没有多大意义。

HashMap爵士也在内部使用hashCode()方法在HashMap中插入一个元素,所以我认为这不是“为什么HashTable允许空键”的正当理由

它将使Map界面更容易使用/更简洁。 null是引用类型的合法值。 使映射能够处理null键和值将消除在调用api之前进行空值检查的需要。 因此,map api在运行时创建的“惊喜”更少。

例如,通常使用map来基于单个字段对同类对象的集合进行分类。 当map与null兼容时,代码将更简洁,因为它只是一个没有任何if语句的简单循环(当然你需要确保集合没有null元素)。 没有分支/异常处理的代码行更少,逻辑上更正确。

另一方面,不允许null不会使地图界面更好/更安全/更容易使用。 依靠map拒绝null是不切实际的 - 这意味着抛出异常,你必须捕获并处理它。 或者,为了摆脱异常,你必须确保在调用map方法之前没有任何东西 - 在这种情况下你不关心map是否接受null,因为你无论如何都要过滤输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM