Capacity:hash表里bucket的数量
Initial capacity:创建hash表的时 bucket的数量 (java使用2的整数次方,对处理器来说,除法和取模是最慢的两种操作,所以如果hash表长度是2的整数次方,就能用掩码代替除法。)
Size : 当前表的数量
Load factor:size/ capacity 负载教轻的表会有较少的冲突,因此插入和查找速度会比较快
当load factor达到阀值,容器会自动将capacity增大一倍,然后将现有的对象分配到新bucket(rehash) 缺省会用0.75的load factor。
好的hashCode()应该能生成均匀分布的值
HashMap的put
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode()); //根据key的hashcode再hash一下(为了抵御"某些不良设计的hashCode函数")
int i = indexFor(hash, table.length);//根据hash值和当前表的长度与运算一下,indexFor这个函数返回的是hash值在table中的位置
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
//hash值相同,key也相同的时候,把旧的值用新值替换,并返回旧的值
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
//相同的hash值 不同的key,该值将放在当前table[i],Entry.next指向之前的entry
addEntry(hash, key, value, i);
return null;
}
Get方法
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());//先根据key的hashcode再hash一下
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.equals(k)))
return e.value;
}//找到index对应的entry,比较entry的hash值,hash值一样,比较key。Key一样的话才返回。
return null;
}