HashMap的工作方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qiaojun1234567/article/details/82191461

HashMap的工作方式

HashMap 是怎样哈希的呢?

HashMap内部有一个Entry数组,大概这个样子

static class Entry<K,V> implements Map.Entry<K,V>{
    final K key;
    V value;
    Entry<K,V> next;
    final int hash;
}

因此,HashMap并不是以键值对的方式存储,而是以数组形式的存储?那么它是如何做到O(1)的效率的呢?

这就需要了解散列的知识,也就是 哈希散列

就是要把我们的 key 与数组索引(0, 1, 2,3,4..)做一个映射,让我们来看看HashMap put()方法的实现

public V put(K key, V value) {
    if (key == null) {
        return putForNulllKey(value);
    }
    int hash = hash(key.hashCode);
    int i = indexFor(hash, table.length);
    // 遍历 i 号桶
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && (k = e.key) == key && key.equals(k)) {
            V oldValue = e.value;
            e.value = value;
            e.recordAcess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(hash, key, value,i);
    return null;
}
  • 首先检查所给的键值key是否为null,如果是null,那么它将会被存储在0号位置。因为null的hashcode值就是0
  • 通过 key. hashCode() 的key对应的hashCode值,为了让所得到的hash值限制在数组索引范围内,调用hash(key.hashCode()),在这里面将会做一些位移运算。
  • indexFor() 方法得到在Entry数组中的确切位置
  • 这里是最重要的部分,如果两个key具有相同的hashCode怎么办?将会存储在相同的桶里面,这里的桶实际上是一个链表结构。所有具有相同hash值的键值都会存储在同一个链表里,并且通过equals()比较键是否相等。

猜你喜欢

转载自blog.csdn.net/qiaojun1234567/article/details/82191461