hashmap源码分析
?
? ? ? ?数组的下标是通过key值的hash值与数组的长度计算出来的。而链表是用用来存放一些具有相同的hashcode, 不是同一个对象或者对象的equals方法不相等的对象,后put过来的这些对象的会放在链表的头部位置。
?
? ? ??看看它的put方法,在源码部分加了一些注释:
public V put(K key, V value) {K k = maskNull(key);//HashMap可是支持空值的哟 int hash = hash(k);//做一些数据处理 int i = indexFor(hash, table.length);//根据key值的hash值与数组的长度计算出来数组的下标 //下面这个for循环用来判断put进来的key值此数组位置上的链表中的Entry是否hash和equals方法都相等,如果 //相等就替换此位置的值,并返回替换之前的值。 for (Entry<K,V> e = table[i]; e != null; e = e.next) { if (e.hash == hash && eq(k, e.key)) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } }//如果不相等就将这个元素放置到链表中,且在链表的头部。 modCount++; addEntry(hash, k, value, i); return null; } void addEntry(int hash, K key, V value, int bucketIndex) {//新元素放置在链表的头部Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<K,V>(hash, key, value, e); if (size++ >= threshold) //超过数组的阀值大小就扩大两倍。 resize(2 * table.length); }static int indexFor(int h, int length) { return h & (length-1); } static int hash(Object x) { int h = x.hashCode(); h += ~(h << 9); h ^= (h >>> 14); h += (h << 4); h ^= (h >>> 10); return h; }?
?
?
hashset的底层其实也是用的是HashMap 。