HashMap中有一些我们容易忽视的点,

Java代码

publicVput(Kkey,Vvalue){

if(table==EMPTY_TABLE){

inflateTable(threshold);

}

if(key==null)

returnputForNullKey(value);

inthash=hash(key);

inti=indexFor(hash,table.length);

for(Entry<K,V>e=table[i];e!=null;e=e.next){

Objectk;

if(e.hash==hash&&((k=e.key)==key||key.equals(k))){

VoldValue=e.value;

e.value=value;

e.recordAccess(this);

returnoldValue;

}

}

modCount++;

addEntry(hash,key,value,i);

returnnull;

}

由上述代码知道,hash值是用来确定bucketIndex,equals是用来和链表上的值比较,因此对于key是自定义的类,强烈建议重写hashCode和equals方法。

再看如下代码下载

Java代码

voidaddEntry(inthash,Kkey,Vvalue,intbucketIndex){

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代码

staticintindexFor(inth,intlength){

//assertInteger.bitCount(length)==1:"lengthmustbeanon-zeropowerof2";

returnh&(length-1);

}