数据结构
- transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
- table中的每一个元素是一个链表的头结点,这些链表称为bucket
- size——HashMap包含的entry个数
- threshold——触发HashMap.resize的阈值
PUT
- 通过
int hash = hash(key);
int i = indexFor(hash, table.length);
确定key所在bucket
- 从头遍历bucket,如果有key相等的entry,则返回oldValue,将原entry的value置为newValue;如果bucket中没有key相等的entry,则用<key,value>新建entry插入HashMap
- 在插入新entry时(之前),HashMap会检查当前size的大小,如果size>=threshold,则执行resize。
- 插入新entry后返回null
GET
- 通过
<span style="white-space:pre"> </span>int hash = hash(key);
int i = indexFor(hash, table.length);
确定key所在bucket
- 从头遍历bucket,如果有key相等的entry,返回value。否则,返回null。
RESIZE
resize过程中,程序会新建一个newTable(大小为2*table.length),将table中的entry移动到newTable中(不是简单的移动)。然后将newTable作为table。
如果在resize过程中有多个线程在执行HashMap.put,有可能产生一个比较严重的BUG——HashMap.get时发生死循环(参考:http://blog.youkuaiyun.com/yinhesky/article/details/9061497)
HashCode
The hash code of a map is defined to be the sum of the hash codes ofeach entry in the map's entrySet() view.
来自 <http://docs.oracle.com/javase/6/docs/api/java/util/Map.html#hashCode()>
线程不安全