关于HashMap put()和get()方法如何工作的内部结构(仅基本逻辑)

时间:2012-07-19 11:31:44

标签: java data-structures hashmap hashtable

当我们使用HashMap方法将一个关键实例说“key”和一个Value实例在put()类中说“value”时,HashMap类在内部执行什么操作。当我们说hashMap.get(key)时,它如何检索值?

修改:我不想在此处提供详细信息,主要是试图了解equals()hashcode()put()get()方法的大局和作用{1}}操作。

3 个答案:

答案 0 :(得分:17)

如果您谈论更高的图片,就像下面一样。在这里​​,我将项目称为key Map

放置物品。

  1. 计算密钥的hashcode
  2. 如果basket存在hashcode,则在密钥上使用equals方法搜索该篮子中的密钥,以确定是否要添加或替换该元素。
  3. 如果不存在则创建新的篮子(重新散列)并将该元素添加到该篮子中。
  4. 获取:

    1. 获取密钥的hashcode
    2. 去那个篮子
    3. 在密钥上使用equals进行迭代将从该篮子中返回该元素。

答案 1 :(得分:1)

这是在IBM jdk 1.6中完成的(我相信它对所有供应商来说都是一样的)

修改

关于equalshashcode您可能有兴趣看到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

Collection framework enhancements