关于字符串String关键字的HashCode散列函数,我们之前已经学习并实现过了,其中一个比较好的散列函数如下:
public static int hash(String key, int tableSize){
int hashVal = 0;
for (int i = 0; i < key.length(); i ++){
hashVal = 37 * hashVal + key.charAt(i);
}
hashVal %= tableSize;
//产生负数的情况
if (hashVal < 0){
hashVal += tableSize;
}
return hashVal;
}
如上,我们将其封装为一个静态方法,提供字符来调用,这样的实现存在一个不足之处是,我们要获取字符串的hashCode时,都必须重新计算一次,这样的操作明显是耗时的。
因此,我们提出这样要给优化:每个String对象内部都存储它的hashCode值,该值初始化为0,但若hashCode被调用时,那么这个值就会被记住。这样,我们就能避免对同一个String对象的2次计算了。这个优化,我们称为 闪存散列代码
public final class String{
private int hash = 0;
public int hashCode(){
if (hash != 0){
return hash;
}
for (int i = 0; i < length(); i ++){
hash = hash * 31 + (int) charAt(i);
}
return hash;
}
}
当然闪存散列代码之所以有效,只是因为String类型是不可改变的:要是String类型允许变化,那么它会使得hashCode无效。