HashMap底层数据结构为哈希表
初始容量
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;
扩容的临界点,当容量达到该值时则扩容
int threshold;
更新HashMap的次数,每次对HashMap进行操作就会+1
transient int modCount;
构造方法
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); }
put方法
public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
putVal方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; //桶未初始化或者未扩容的时候,先用resize()进行扩容 if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; //hash函数,,计算key放置的桶的位置,(n-1)&hash实际上算的是hash%n,计算更快 //如果是空桶,则创建新的键值对节点,放进数组里面 if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); //如果不是空桶 else { Node<K,V> e; K k; //如果key已经存在,则替代原来的键值对 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; //key不存在,按红黑树插入 else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); //key不存在,按链表方式插入 else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); //如果大于链表最大长度,则转为红黑树结构 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; //判断是否大于扩容临界点,进行扩容 if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
removeNode方法
final Node<K,V> removeNode(int hash, Object key, Object value, boolean matchValue, boolean movable) { Node<K,V>[] tab; Node<K,V> p; int n, index; if ((tab = table) != null && (n = tab.length) > 0 && (p = tab[index = (n - 1) & hash]) != null) { Node<K,V> node = null, e; K k; V v; //待删除元素未桶的首元素 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) node = p; //待删除元素在桶中但不是首元素 else if ((e = p.next) != null) { //在红黑树中 if (p instanceof TreeNode) node = ((TreeNode<K,V>)p).getTreeNode(hash, key); //在链表中 else { do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { node = e; break; } p = e; } while ((e = e.next) != null); } } //matchValue为true,表示value相等才进行删除操作 //matchValue为false,表示只要key相等就进行删除操作 if (node != null && (!matchValue || (v = node.value) == value || (value != null && value.equals(v)))) { if (node instanceof TreeNode) ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable); else if (node == p) tab[index] = node.next; else p.next = node.next; ++modCount; --size; afterNodeRemoval(node); return node; } } return null; }