2)我们可以看到在putVal()方法中key在这里执行了一下hash()方法,来看一下Hash方法是如何实现的 。
static final int hash(Object key){int h;/*1)如果key等于null:可以看到当key等于null的时候也是有哈希值的 , 返回的是0.2)如果key不等于null:首先计算出key的hashCode赋值给h,然后与h无符号右移16位后的二进制进行按位异或得到最后的hash值*/return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }从上面可以得知HashMap是支持Key为空的 , 而HashTable是直接用Key来获取HashCode所以key为空会抛异常 。
{其实上面就已经解释了为什么HashMap的长度为什么要是2的幂因为HashMap 使用的方法很巧妙 , 它通过 hash/*1)如果key等于null:可以看到当key等于null的时候也是有哈希值的 , 返回的是0.2)如果key不等于null:首先计算出key的hashCode赋值给h,然后与h无符号右移16位后的二进制进行按位异或得到最后的hash值*/return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }在putVal函数中使用到了上述hash函数计算的哈希值:
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {。。。。。。。。。。。。。。if ((p = tab[i = (n - 1) }final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node[] tab; Node p; int n, i;/*1)transient Node[] table; 表示存储Map集合中元素的数组 。2)(tab = table) == null 表示将空的table赋值给tab,然后判断tab是否等于null , 第一次肯定是null3)(n = tab.length) == 0 表示将数组的长度0赋值给n,然后判断n是否等于0 , n等于0由于if判断使用双或 , 满足一个即可 , 则执行代码 n = (tab = resize()).length; 进行数组初始化 。并将初始化好的数组长度赋值给n.4)执行完n = (tab = resize()).length , 数组tab每个空间都是null*/if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;/*1)i = (n - 1) 根据键值对创建新的节点放入该位置的桶中小结:如果当前桶没有哈希碰撞冲突 , 则直接把键值对插入空间位置*/if ((p = tab[i = (n - 1)else {// 执行else说明tab[i]不等于null , 表示这个位置已经有值了 。Node e; K k;/*比较桶中第一个元素(数组中的结点)的hash值和key是否相等1)p.hash == hash :p.hash表示原来存在数据的hash值hash表示后添加数据的hash值 比较两个hash值是否相等说明:p表示tab[i] , 即 newNode(hash, key, value, null)方法返回的Node对象 。Node newNode(int hash, K key, V value, Node next){return new Node<>(hash, key, value, next);}而在Node类中具有成员变量hash用来记录着之前数据的hash值的2)(k = p.key) == key :p.key获取原来数据的key赋值给kkey 表示后添加数据的key 比较两个key的地址值是否相等3)key != null// hash值不相等或者key不相等;判断p是否为红黑树结点else if (p instanceof TreeNode)// 放入树中e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);// 说明是链表节点else {/*1)如果是链表的话需要遍历到最后节点然后插入2)采用循环遍历的方式 , 判断链表中是否有重复的key*/for (int binCount = 0; ; ++binCount) {/*1)e = p.next 获取p的下一个元素赋值给e2)(e = p.next) == null 判断p.next是否等于null , 等于null , 说明p没有下一个元素 , 那么此时到达了链表的尾部 , 还没有找到重复的key,则说明HashMap没有包含该键将该键值对插入链表中*/if ((e = p.next) == null) {/*1)创建一个新的节点插入到尾部p.next = newNode(hash, key, value, null);Node newNode(int hash, K key, V value, Node
推荐阅读
-
白光莹|叶罗丽:庞尊竟给白光莹戴上戒指,捧头共浴,他和白光莹又甜又虐
-
土耳其总统|土耳其再派科考船赴东地中海进行地震勘探
-
J罗|安切洛蒂梅开二度!2500万敲定J罗签约四年,3400万悍将已在路上
-
-
网友|“现男友”李现为新戏苦练骑马,陈建斌骑假马电视剧差评如潮
-
-
金牛座男生|更有利于身体健康?,中老年夫妻一个星期“互动”多少次
-
解说小鱼▲最后一名是adc的噩梦,英雄联盟:盘点LOL中被拳头移除的最屌大招
-
清华细说教育|“文艺女神”江一燕成名的背后,是这几个大款富豪在推波助澜?
-
特斯拉|特斯拉侧目!奇瑞引入区块链记录行车数据:保证数据真实不可篡改
-
路人说球|惨遭李氏父子痛斥,「尴尬时刻」我太难了!李金效低级失误
-
火箭大狗熊|哈登是个例外,火箭破釜沉舟!14人被放上货架?只为23+11+3中锋
-
【爱心妈妈爱世界|当她侧身那一刻,这腿长的太不真实了,张馨予即兴表演太空步】
-
宋江为什么能做大哥这3点让他在众人中脱颖而出,值得学习!
-
人民日报海外版|将成电子化支付重要补充 数字人民币离我们更近了
-
小橘的潮时尚|小橘街拍,难于驾驭的油绿色,小姐姐穿出华贵
-
周野芒|演员周野芒:与奚美娟离婚后,火速再婚琼女郎,儿子不跟他姓
-
-
“出轨门”7年,宋喆变大叔,宝强开辟新天地,马蓉现状让人意外
-