HashMap的put流程原理详细讲解

文章目录

    • HashMap的put流程
      • 个人故事
      • PUT流程
      • 总结

HashMap的put流程

个人故事

我最近在面试找Java岗位开发,最近也是面了几家,有一家问我给我讲一下什么HashMap的put流程,实话我是真的这个是背的,面试官上来就直接打断了我的诉说。讲重点,说真的,咱们背的面试题,都是东一道西一道的,他们这些提供文章的都是讲的一些皮毛,甚至都不知道是在哪里copy的 ,好的文章确实有,但很少。问的我哑口无言,就纯背面试题,真的是能把人害死,所以我要做一份文章,彻底弥补一下理论知识的情况。

PUT流程

 首先put的过程中首先是调用了hash方法
    public V put(K key, V value) {
   
        return putVal(hash(key), key, value, false, true);
    }

    static final int hash(Object key) {
   
        int h;
        
        //hash方法进行判断key是否为空 如果为空hash值则为0,
        //如果不为空进行获取key的hashCode()值进行异域计算,
        //那这一块什么意思呢?说实话刚开始我也不懂得什么意思,我看面试题我也就是异域计算
		
		//实则意思就是 获取hashCode的int值,而h和HashCode的值是一样的然后h进行位运算
		
		//Map<String,String> param = new HashMap<>();

        //param.put("张三","123");
        //System.out.println(param.hashCode()); 结果:774889
        //System.out.println(param.hashCode()>>>16); 结果:11
		//这里说的就是>>>计算的时候要转换为二进制
		//774889的二进制为:10111010110110010001
		//无符号右移操16位		就等于二进制1011
		//意思就是
		  // 	10111101001011101001无符号右移操16位等于00000000000000001011
			//1011等于十进制11
		//(h = key.hashCode()) ^ (h >>> 16)	
		//			 774889	 ^	11
		//10111101001011101001^00000000000000001011	
		//10111101001011101001
		//00000000000000001011
//   答案  10111101001011100010
//		这里说的就是11计算成二进制为1011 既然1011不够774889那么长那就补前面补0
//		补到一样长
//		我们只计算1011同位的 
//		如果两个相应的位相同,结果为0。
//		如果两个相应的位不同,结果为1。
//		结果就是:774882
//		这下我们就明白了什么是异域计算了,面试官不管问不问,咱们最起码能知道是怎么计算的了
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

 
/**
 * @param hash 是key的整型hash值
 * @param key  存储的key
 * @param value 存储的value
 * @param onlyIfAbsent 当调用hashmap的putIfAbsent方法时才会为true,这个为true的时候,key的value为null的时候才会进行修改值
 * @param evict只有在方法 afterNodeInsertion(boolean evict) { }用到,可以看到它是一个空实现,因此不用关注这个参数
 * @return previous value, or null if none
 */
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
			   boolean evict) {
   
    /**
    tab : 创建临时节点表
    p : 临时节点
    n : hashMap.table 的长度
    i : 记录table的索引
    */
	Node<K,V>[] tab; Node<K,V> p; int n, i;
	//这里是table赋值给临时节点tab判断是否null,为null时进行resize()方法初始化数组
    //以及下次要扩容的阈值
    // 当 tab !=  null 接着判断 tab的长度也不能为0 , 否则还是调用 resize() 方法进行初始化。
	if ((tab = table) == null || (n = tab.length) == 0)
        // 把初始化后的 table 赋给 tab table的长度赋给 n
		n = (tab = resize()).length;
	//根据当前key的hash值找到它在数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小电玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值