HashMap和Hashtable中的hash值是怎么计算的

上一篇讲了String、Integer复写了Object中的hashCode方法,而对于HashMap或类对象来说是直接使用了Object中的hashCode方法。正文如下:

public class Test {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("key", "value");
        Hashtable table = new Hashtable();
        table.put("key", "value");
        Test test = new Test();
        test.hashCode();
    }
}

对于HashMap中 key值的hash计算源码如下:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

可以看到 HashMap 中的key值可以为null,key值的hash值的计算方法为:key的hash值高16位不变,低16位与高16位异或作为key最终的hash值。(h>>>16,表示无符号右移16位,高位补0)

对于Hashtable中的key值计算的hash源码如下:

public synchronized V put(K key, V value) {
    // Make sure the value is not null
    if (value == null) {
        throw new NullPointerException();
    }

    // Makes sure the key is not already in the hashtable.
    Entry<?,?> tab[] = table;
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    @SuppressWarnings("unchecked")
    Entry<K,V> entry = (Entry<K,V>)tab[index];
    for(; entry != null ; entry = entry.next) {
        if ((entry.hash == hash) && entry.key.equals(key)) {
            V old = entry.value;
            entry.value = value;
            return old;
        }
    }

    addEntry(hash, key, value, index);
    return null;
}

可以看到Hashtable线程安全是因为添加了 synchronized 关键字,同时 Hashtable key值是不可以为空的。

其中 int index = (hash & 0x7FFFFFFF) % tab.length;

为了在hash为负值的情况下,去掉起符号位,所以和0x7FFFFFFF进行&操作。0x7FFFFFFF 二进制 0111 1111 1111 1111 1111 1111 1111 1111,负数与其进行&操作将产生一个正整数。

参考及扩展阅读:
https://www.cnblogs.com/liujinhong/p/6576543.html
hashcode的解析 https://www.jianshu.com/p/2c1b6dd312eb

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值