每个人都知道hashmap包含唯一的键。但是我想知道它是如何保持唯一性的?
假设我们在hashmap中插入100个数据,然后在同一hashmap中插入重复的键和值。我知道它会覆盖这个值。但我想知道它会检查hashmap中已经存储的所有之前的密钥,然后覆盖新密钥。
或者如果它每次都检查以前的所有键,那么它将需要更多的时间。所以请告诉我正确的答案。
请看下面这张照片(https://www.bigocheatsheet.com/)
哈希集合具有O(1)插入复杂性,这意味着操作不取决于数据结构中已经存在多少数据点。顾名思义,键被散列到桶中。如果要查找keya
的值,则会获取该键,并使用哈希函数将该值映射到特定的内存位置。不需要查找任何其他值。
例外情况是由于维数降低而必然发生的哈希冲突。在使用has函数后,不同的密钥max解析为相同的散列,从而落在同一个bucket中。在这种情况下,必须进行其他检查(这就是为什么您总是必须覆盖hashcode和equals的原因)。有关这方面的更多信息,请参见:https://stackoverflow.com/a/19691998/3244464
您需要知道HashMap
的内部表示形式。
实际上,它是一个键值项列表的数组,我们可以用图形表示它,如下所示:
bucket
position
--------
0 NULL
1 --> (K1, V1) --> (K47, V47)
2 NULL
3 NULL
...
54 --> (K89, V89)
...
当执行put操作时,put(键,值)首先由代码检索键的哈希代码。在特定存储桶的列表中搜索时,需要使用带有模块操作的该值。然后,它在该列表上逐个元素执行搜索,并执行equals方法来检查键是否已经存在。如果键存在,则只替换值,如果不存在,则会在列表末尾添加一个新的成对键和值。
HashMap的伪代码类似于以下内容:
public HashMap {
private List<List<KeyValue<K, V>>> keyValuesBuckets;
public void put(K key, V value) {
int hash = key.hashCode();
int bucketPosition = hash % keyValuesBuckets.size();
for (KeyValue kv : keyValuesBuckets.get(bucketPosition)) {
if (kv.getKey().equals(key)) {
// Key is present change the value and exit
kv.setValue(value);
return;
}
}
// Key is not present
keyValuesBuckets.get(bucketPosition).add(new KeyValue(key, value));
}
请注意,代码不是真正的代码。例如,没有检查空值,但它让您了解如何使用hashCode和equals方法检查相等性。
要更深入地了解其工作原理,请从[hashCode
][1]的定义开始:
返回对象的哈希码值。支持此方法是为了哈希表的利益,例如HashMap提供的哈希表。
和[等于
][2]
在javadoc中,您可以找到equals
和hashCode
必须提供的契约,以便类可以用作HashMap
中的键:
hashCode的一般约定是:在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode时,hashCode方法必须一致地返回相同的整数,前提是在对象的equals比较中使用的信息没有被修改。从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。如果根据equals(Object)方法,两个对象相等,那么对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果。如果根据equals(java.lang.Object)方法,两个对象是不等的,那么对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这不是必需的。然而,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。[1]: https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode-- [2]: https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-爪哇。lang.反对-
假设我们有一个名为hsm的hashMap,我想要hsm的值。获取(无效密钥)。因为invalidKey没有映射,它将为我返回一个空值,但我希望它为我返回invalidKey。我已经知道了一种方法,我们首先检查hsm。containsKey(invalidKey)以确保其有效且不会覆盖数组中的值,但是否还有其他方法?
在flutter应用程序中存储key.jks文件对于flutter应用程序发布是安全的吗? 存储库密码、keyPassword、keyAlias 我的key.properties文件:
问题内容: 我有一个字段,例如,在表中应该是唯一的。 使用Spring / Hibernate验证进行验证的最佳方法是什么? 问题答案: 一种可能的解决方案是创建自定义约束(和相应的验证器)。并要查找数据库中的现有记录,请提供(或Hibernate)to 的实例。 EntityManagerAwareValidator ConstraintValidatorFactoryImpl 唯一键 Uniq
我浏览了HashMap的源代码,并提出了一些问题。PUT 方法采用键和值并执行 > 密钥哈希码的哈希函数。 使用从上一步获得的哈希计算这对的桶位置 例: 创建大小为 10 的哈希映射。 调用 put(k,v) 三次,并假设这 3 个占用存储桶 loc 7、8 和 9 调用 put 第 4 个 K,V 对,并且发生以下 hash() 使用 key.hashcode() 和 hash 计算来调用 in
问题内容: 是否总是需要在HashMap中检查密钥是否存在? 我有一个说有1000个条目的HashMap,我正在考虑提高效率。如果HashMap的访问非常频繁,则每次访问时检查密钥是否存在将导致大量开销。相反,如果键不存在,因此发生异常,我可以捕获该异常。(当我知道这种情况很少发生时)。这将减少对HashMap的访问。 这可能不是一个好的编程习惯,但是它将帮助我减少访问次数。还是我在这里想念什么?
问题内容: 我有一个字段,例如,在表中应该是唯一的。 使用Spring / Hibernate验证进行验证的最佳方法是什么? 问题答案: 一种可能的解决方案是创建自定义约束(和相应的验证器)。并在数据库中查找现有记录,请提供(或Hibernate )to 的实例。 EntityManagerAwareValidator ConstraintValidatorFactoryImpl 唯一键 Uniq