HashMap
HashMap用一个Node数组保存所有的k-v对,数组中的一个位置被称为bucket,一个bucket中的第一个Node(也就是在Node数组中通过下标能访问到的那一个)是一个单链表或者一棵红黑树的根节点,所有被hash到同一个bucket的k-v对被保存在这个单链表或红黑树中(取决于同一个bucket中元素的数量,达到8成为红黑树,减到6成为链表)。Node的数据结构如下:
final int hash; final K key; V value; Node<K,V> next;
HashMap的默认初始容量为16,加载因子为0.75,且容量必为2的幂,这是为了根据key的hashcode计算桶的位置时可以不通过除法进行计算,而且采用&的方式(hash(key)&(数组长度-1)==hash(key)%数组长度)。
放入新k-v对时,首先根据k的hash值计算bucket位置,发生碰撞时通过key.equals()判断key值是否相等,相等则更新value,否则加入新的Node。
HashMap可放入null-null对,hash(null)==0,因此,空key放在第一个bucket。
HashMap线程不安全,1.7rehash时采用头插,多线程下可能出现循环链表,1.8为尾插,避免了循环链表,但任然线程不安全。
HashTable线程安全,使用synchronized锁住整个hash表,k-v不能为null,初始值为11,扩容:newsize = olesize*2+1。