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
推荐阅读
-
【】绿军和少帅史蒂文斯续约 后者带队胜场排队史第4
-
-
『旅客列车』返程高峰来了!广铁广东地区今到旅客56万人
-
快科技|发了1200万美元还要回!FCA要求工人返还停工期多支付的工资
-
-
发布会|证监会批准国际铜交易 交易时间为2020年11月19日
-
怪咖搞笑实在是不想逛了 于是我想出了一个妙法,幽默笑话:昨天陪女友逛街
-
数码东东:还在等?宁可停产也不降价!等等党只能泪流
-
-
「温暖对白」好领导和做好本职工作,哪个最重要?,在日常工作中
-
天涯明月刀手游|天涯明月刀手游:你所不知道的琅纹小技巧,想要提升战斗力不是问题!
-
「美国」实在太惨烈了!5月4日15时,绝望的消息再从美国传来
-
-
『电工』在农村干电工,一月能赚多少钱?答案揭晓!网友:远比打工强!
-
王者荣耀|28号限定返场,获取条件公布,部分玩家无法购买
-
「2000个扶贫项目」新疆加大非贫困县扶贫投入 逾2000个扶贫项目巩固脱贫成果
-
李若彤|李若彤:情断富商之后单身至今,56岁无儿无女,结婚全靠缘分
-
-
-
【吉利服】俄专家敢于直言戳破牛皮,美叫嚣在中国家门口动手他们也不畏惧