当我们使用HashMap
方法将一个关键实例说“key”和一个Value实例在put()
类中说“value”时,HashMap
类在内部执行什么操作。当我们说hashMap.get(key)
时,它如何检索值?
修改:我不想在此处提供详细信息,主要是试图了解equals()
和hashcode()
和put()
和get()
方法的大局和作用{1}}操作。
答案 0 :(得分:17)
如果您谈论更高的图片,就像下面一样。在这里,我将项目称为key
Map
放置物品。
hashcode
basket
存在hashcode
,则在密钥上使用equals
方法搜索该篮子中的密钥,以确定是否要添加或替换该元素。获取:强>
hashcode
equals
进行迭代将从该篮子中返回该元素。答案 1 :(得分:1)
这是在IBM jdk 1.6中完成的(我相信它对所有供应商来说都是一样的)
修改强>
关于equals
和hashcode
您可能有兴趣看到this发布。
编辑结束
/**
* Maps the specified key to the specified value.
*
* @param key
* the key
* @param value
* the value
* @return the value of any previous mapping with the specified key or null
* if there was no mapping
*/
@Override
public V put(K key, V value) {
return putImpl(key, value);
}
V putImpl(K key, V value) {
Entry<K,V> entry;
if(key == null) {
entry = findNullKeyEntry();
if (entry == null) {
modCount++;
if (++elementCount > threshold) {
rehash();
}
entry = createHashedEntry(null, 0, 0);
}
} else {
int hash = key.hashCode();
int index = hash & (elementData.length - 1);
entry = findNonNullKeyEntry(key, index, hash);
if (entry == null) {
modCount++;
if (++elementCount > threshold) {
rehash();
index = hash & (elementData.length - 1);
}
entry = createHashedEntry(key, index, hash);
}
if ((cache != null) && (hash >> CACHE_BIT_SIZE == 0)
&& (key instanceof Integer)) {
cache[hash] = value;
}
}
V result = entry.value;
entry.value = value;
return result;
}
答案 2 :(得分:1)
从java 8
开始,HashMap
对象的性能有所改善,其中密钥中存在大量冲突,使用平衡树而不是链接列表来存储地图条目。主要思想是,一旦哈希桶中的项目数量增长超过某个阈值,该桶就会从使用链接的条目列表切换到平衡树。在高哈希冲突的情况下,这将改善从O(n)
到O(log n).
的最坏情况性能
基本上当存储桶变得太大(目前:TREEIFY_THRESHOLD = 8
)时,HashMap
会动态地将其替换为树形图的临时实现。通过这种方式而不是悲观O(n)
,我们会变得更好O(log n)
。
TreeNodes
的Bins(元素或节点)可以像其他任何一样遍历和使用,但是当人口过多时还支持更快的查找。但是,由于正常使用的绝大多数垃圾箱人口过多,因此在表格方法过程中可能会延迟检查树箱的存在。
Tree
个bin(即其元素都为TreeNodes
的bin)主要由hashCode排序,但在tie的情况下,如果两个元素具有相同的“class C implements Comparable<C>
” ,然后输入他们的compareTo()
方法进行排序。
因为TreeNodes
大约是常规节点大小的两倍,所以我们只在容器包含足够节点时才使用它们。当它们变得太小(由于移除或调整大小)时,它们会转换回普通箱(目前:UNTREEIFY_THRESHOLD = 6
)。在分布均匀的用户hashCodes
的用法中,很少使用树容器。
链接到java doc