代码前的文档

  • hashMap 允许null key并且非线程安全,hashTable线程安全不允许null key.

  • 影响hashMap性能的两个重要参数是capacity和load fator,因为他们关系着hashMap的自动扩容,
    capacity默认是16,而且必须是2的n次方,最大capacity是2的30次方。 load factor默认是0.75

  • 遍历一个hashMap的时间跟 (capacity + size)成正比.(why? TODO)

  • 当大量的数据存储在hashmap中时,提供一个很大的capacity有助于提高性能,因为可以防止hash一直自动扩充容量,当有很多hash key 出现hash冲突时会降低性能.

  • 当key时 comparable的时候,会用到 comparison 来降低冲突. (why? TODO)

  • HashMap的Iterator,所有的 view methods 都是fail-gast的,当HashMap结构改变(put了新的key或者删除了key,修改value不算结构改变)了之后会报ConcurrentModificationException。

  • ConcurrentModificationException 只能作为标志有错误使用,不能这么使用:当catch住ConcurrentModificationException时,做一些操作试图修正无错误ConcurrentModificationException不做任何保证

Implementation notes
  • TODO

源码解读

常量

DEFAULT_INITIAL_CAPACITY 默认初始容量 16
MAXIMUM_CAPACITY 最大容量 2的30次方
DEFAULT_LOAD_FACTOR load factor 0.75
TREEIFY_THRESHOLD 8
UNTREEIFY_THRESHOLD 6
MIN_TREEIFY_CAPACITY 64

确定hash桶索引位置

方法一:
static final int hash(Object key) { //jdk1.8 & jdk1.7
int h;
// h = key.hashCode() 为第一步 取hashCode值
// h ^ (h >>> 16) 为第二步 高位参与运算
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
static int indexFor(int h, int length) { //jdk1.7的源码,jdk1.8没有这个方法,但是实现原理一样的
return h & (length-1); //第三步 取模运算
}

put方法

扩容

线程安全

参考