文章目录
-
- 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值找到它在数组