今天无意中想到了HashMap,复习巩固一下,才发现jdk8已经对HashMap做了提升;
HashMap 与 HashTable都是Map的实现类,都属于一种容器,对于容器的操作无非是就 查数据或者插入数据,但是Map对数据操作有自己的规则,Map的每一个元素是由两部分组成,分别是key(键) 和value(值);这里Map是通过查找key的方式来获取相应的value,并且key的值不可以重复。
HashMap底层就是一个数组结构,数组中的每一项又是一个链表。在jdk7之前是一个Entry数组(table),数据的存储(key,value)都是以Entry的形式放在数组中,而这个Entry存放在数组的哪个位置取决于key的hashcode来计算,然后根据计算的值使用indexfor根据table.length取模来算出table的下标,当获取的下表已经存在元素(hash碰撞),则采用equals方法判断是否相同,如果相同,则将数组对应的链表上(旧值),将新增的值放入数组对应的位置上;通过Entry的一个属性(next)来进行关联链表;
对应核心方法的源码:
put方法:
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
get方法:
public V get(Object key) { //null值默认取table[0]位 if (key == null) return getForNullKey(); Entry<K,V> entry = getEntry(key); return null == entry ? null : entry.getValue(); }
final Entry<K,V> getEntry(Object key) { int hash = (key == null) ? 0 : hash(key); //遍历查到key对应的value for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } return null; }
对于jdk8HasdMap的优化点,在jdk7之前,当发送hash冲突的时候,就将对应的节点以链表的形式存储;
如果存在比较极端的情况&#x