返回

揭开单线程HashMap的神秘面纱,3分钟轻松GET!

后端

在程序员的工具箱中,HashMap可谓是一颗闪耀的明星,它是一种高效的键值对数据结构,广泛应用于各类场景。作为一名技术博客专家,我将带你深入浅出地领略单线程HashMap的魅力。

基础概念:

HashMap本质上是一个哈希表,它使用哈希函数将键映射到一个特定的桶(bucket)中。每个桶通常是一个链表,用来存储具有相同哈希值的键值对。为了防止哈希冲突(多个键映射到同一个桶),HashMap会在达到一定负载因子时进行扩容。

源码解读:

public class HashMap<K, V> {
    private transient Node<K,V>[] table;
    private transient int size;
    private transient int threshold;
    private final float loadFactor;
    
    public HashMap() {
        this(16, 0.75f);
    }
    
    public HashMap(int initialCapacity, float loadFactor) {
        this.loadFactor = loadFactor;
        this.threshold = (int) (initialCapacity * loadFactor);
        table = new Node[initialCapacity];
    }
    
    public V get(Object key) {
        int hash = key.hashCode();
        int i = indexFor(hash, table.length);
        Node<K,V> e = table[i];
        while (e != null) {
            if (e.hash == hash && e.key.equals(key)) {
                return e.value;
            }
            e = e.next;
        }
        return null;
    }
    
    public V put(K key, V value) {
        int hash = key.hashCode();
        int i = indexFor(hash, table.length);
        for (Node<K,V> e = table[i]; e != null; e = e.next) {
            if (e.hash == hash && e.key.equals(key)) {
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }
        addEntry(hash, key, value, i);
        return null;
    }
    
    private void addEntry(int hash, K key, V value, int bucketIndex) {
        Node<K,V> newNode = new Node<>(hash, key, value, null);
        Node<K,V> e = table[bucketIndex];
        table[bucketIndex] = newNode;
        newNode.next = e;
        if (size++ >= threshold) {
            resize(2 * table.length);
        }
    }
}

工作原理:

  • 哈希函数: HashMap利用哈希函数将键映射到一个桶中,桶的索引通过indexFor方法计算得到。
  • 链表存储: 每个桶是一个链表,用来存储具有相同哈希值的键值对。当发生哈希冲突时,新插入的键值对会被添加到链表的尾部。
  • 扩容机制: 当HashMap中的元素数量达到一定比例(负载因子)时,会触发扩容操作。扩容会创建一个新的、更大的哈希表,并将原有元素重新哈希分配到新的表中。
  • 链表转红黑树: 在JDK1.8中,HashMap对链表做了优化。当链表长度超过8时,会将链表转换为红黑树,红黑树是一种具有自平衡特性的二叉搜索树,可以提高查找和插入的效率。

总结:

单线程HashMap是一种高效的数据结构,它使用哈希函数和链表(或红黑树)来快速存储和检索键值对。其背后的原理并不复杂,通过结合源码和清晰的解释,我们可以轻松地理解其工作机制。