为什么在哈希映射中使用空值或空键是有用的?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在哈希映射中使用空值或空键是有用的?相关的知识,希望对你有一定的参考价值。
Hashtable
不允许空键或值,而HashMap
允许空值和1空键。
Questions:
- 为什么会这样?
- 在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 Bayers所回答的问题之外,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,因为你无论如何都要过滤输入。
以上是关于为什么在哈希映射中使用空值或空键是有用的?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 codeigniter form_validation 类中允许空值或数值?