HashMap

Posted 皓月行空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap相关的知识,希望对你有一定的参考价值。

1、数据结构

    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
    static final int MAXIMUM_CAPACITY = 1 << 30;
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    static final int TREEIFY_THRESHOLD = 8;
    static final int UNTREEIFY_THRESHOLD = 6;
    static final int MIN_TREEIFY_CAPACITY = 64;

    transient Node<K,V>[] table;
    transient int size;
    transient int modCount;
    int threshold;
    final float loadFactor;


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

    

 

2、核心方法

(1)初始化,初始化指定默认大小=16,加载因子=0.75,如果指定了初始化容量,根据位或运算,最终会成为2的整数幂

public HashMap(int initialCapacity) 
        this(initialCapacity, DEFAULT_LOAD_FACTOR);

public HashMap() 
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted

public HashMap(int initialCapacity, float loadFactor) 
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);


static final int tableSizeFor(int cap) 
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
 

(2)put

3、问题qa

(1)为什么默认的扩展因子是0.75

(2)1.7版本的死循环、1.8版本的死循环

1.7版本 链表头部插入,扩容成为新的链表时,仍然时头部插入,

链表 a,b,c,
线程1完成扩容,c,b,a
线程2,扩容时,显示 a--->null,然后 b-->a-->null,最后 b.next时已经发生变化,又重新指向了a,此时链表是a-->b-->a, 

(3)为什么线程不安全

4、备注
(1)jdk1.8之前是插入链表头部,1.8之后是插入链表尾部

(2)jdk1.8优化,当链表个数>7时,使用红黑树进行管理

以上是关于HashMap的主要内容,如果未能解决你的问题,请参考以下文章

对于HashMap问题的一些解答

HashMap 扩容

为啥在 URL 中缺少尾部斜杠 (/) 时会发生重定向?

HashMap总结

HashMap插入节点详细过程

为啥 HashMap 调整大小以防发生碰撞或最坏的情况