HashMap中有一些我们容易忽视的点,
Java代码
-
public V put(K key, V value) {
-
if (table == EMPTY_TABLE) {
-
inflateTable(threshold);
-
}
-
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;
-
}
由上述代码知道,hash值是用来确定bucketIndex,equals是用来和链表上的值比较,因此对于key是自定义的类,强烈建议重写hashCode和equals方法。
再看如下代码下载
Java代码
-
void addEntry(int hash, K key, V value, int bucketIndex) {
-
if ((size >= threshold) && (null != table[bucketIndex])) {
-
resize(2 * table.length);
-
hash = (null != key) ? hash(key) : 0;
-
bucketIndex = indexFor(hash, table.length);
-
}
-
-
createEntry(hash, key, value, bucketIndex);
-
}
if条件告诉我们rehash的条件要同时满足两个:map中元素个数不小于阀值即容量*负载因子,对应的bucketIndex处有元素。
另外,如下代码作备忘,
Java代码
-
static int indexFor(int h, int length) {
-
// assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
-
return h & (length-1);
-
}