又到了每天读一读源代码的时候啦。今天来看看HashMap
其实原本是想先写HashSet的,不过后来看到HashSet底层是用HashMap实现的,所以就先写HashMap
首先讲一下Map吧,Map是以key-value存储的数据结构,key可以看成是value的索引,作为key的对象集合是不能重复的。
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;
HashMap的默认容量大小是16(记住ArrayList是10)
HashMap设置了一个阈值threshold=capacity * load factor
这也是loadFactor存在的意义,就是当Map的size占容量的比例等于loadFactor时,就会触发扩容。
先讲一下HashMap的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;
}
先通过key计算对应的hash值,
然后通过indexFor方法获取对应存储的数组位置
接下去一个for循环,通过拉链法存储。
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
先判断两个key的hash值是否相同,如果不同则直接跳过
如果相同再判断两个key是否==或者equals。
如果出现相同那么就将对应的value替换。
再讲一个比较正常的方法,get
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
简单看一下,大概就是通过key获取对应的Entry,然后通过Entry获取对应的value。
今天就先到这里,累死咯。。
每天看一点源代码,幸福生活每一天。
网友评论