集合框架——hashCode算法实现

目录

一、hashCode算法实现

二、HashMap中为什么数组的长度为2的幂次方

三、HashMap 在计算bucket位置时,为什么使用 & 与运算代替模运算?

四、自定义 HashMap 容量最好是多少?

五、如何解决Hash冲突


hashcode事一个int类型的数字,从Object的hashCode()方法的注释中可以看出hashcode主要是用于hashMap等类用于寻址的一个参数

一、hashCode算法实现

1、对象默认的hashCode()方法:对象如果没有重写hashCode()方法,那么就是继承Object的hashCode()方法,这是一个本地(native)方法,返回实例对象的内存地址(注释中有说明)

//return distinct integers for distinct objects. (This is typically implemented by 
//converting the internal address of the object into an integer
public native int hashCode();

2、String类的hashCode()方法:String在内存中是以char数组的形式存储的,hashCode()方法是对每个char字符运算得到

//private final char value[];
public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

至于为什么使用31,在《Effective Java》中给出了解释:

因为31是一个奇素数。如果乘数是偶数,并且乘法溢出的话,信息就会丢失,因为与2相乘等价于移位运算(低位补0)。使用素数的好处并不很明显,但是习惯上使用素数来计算散列结果。 31 有个很好的性能,即用移位和减法来代替乘法,可以得到更好的性能: 31 * i == (i << 5) - i, 现代的 VM 可以自动完成这种优化。

3、HashMap的hashCode()方法:hashMap的hashCode是对map中所有Entry的hashCode累加的结果

//(AbstractMap类中)
public int hashCode() {
        int h = 0;
        Iterator<Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext())
            h += i.next().hashCode();
        return h;
    }

而Entry的hashCode计算如下: 

//Entry的hashCode(HashMap类中)
public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }
//Objects类的hashCode
public static in
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值