HashMap源码解析

1.基本结构:
    简单总结一下HashMap:HashMap存储的是存在映射关系的键值对,存储在被称为哈希表的数据结构中,通过计算key的hashCode值来确定键值对在数组中的位置,假如产生碰撞,则使用链表或者红黑树,
    这里需要注意的是,key最好使用不可变类型的对象,否则在key产生变化时,重新计算hashCode值,会与之前的不一样,导致查找错误
    由第一点可知,在存储键值对时我们希望的情况是尽量避免碰撞,这样的话查找效率就会更高,那么如何尽量避免碰撞,核心就在于元素的分布策略和动态扩容;
    所以hashMap的第二个重点就在于在分布策略方面的优化,这里的优化方式为:
2.分布策略:
2.1 数组的长度始终保持为2的次幂
2.2 将哈希值的高位参与运算
2.3 通过位与操作来等价取模操作
第三个重点:
3.动态扩容方面:
由于底层数组的长度始终为2的次幂,因此每次扩容数组长度都是增加一倍,因此数组长度length的二进制表示会在高位多出1bit,二在扩容时length会参与位与操作来确定元素所在数组中的新位置,所以原数组中的元素所在位置要么保持不动,要么就是移动2次幂个位置,这样就能提高动态扩容的效率;
hashMap美中不足的是,它不是线程安全的,可能会在扩容时出现著名的环形链表异常,除此之外,在日常多线程进行put操作时也比较容易出现脏数据读写的问题
环形链表的产生:

在JDK1.7到JDK1.8中发生了很大的变化,很多可能会感觉既然都更新,那1.7就没有必要再看了,我认为读源码的目的是为了学习其中的思想,并尝试在今后的开发中进行运用

hashcode值  与  数组长度  相除取余

hashcode值  与 (数组长度 - 1)  进行位与运算
数组长度保证为2的次幂原因:(数组长度 - 1)之后的值所有位上的值都为1,进行位与运算时结果就是低位的原值
且能达到与取余结果一致

在jdk1.8中,如果链表长度大于8且节点数组长度大于64的时候,就把链表下所有的节点转为红黑树。

程序员发展之路:
balance
care
type

有更多的面试机会,男女比例平等,

提升自己的竞争力

比较细心,更站在别人的角度看问题,审美更加在线

平衡自己的生活和工作,

提升自己:从工作中找一些自己可以做的事情做,在业务中找突破点提升自己

30岁之前给自己找赛道,30岁之后在赛道上去冲刺,年龄危机

提前做一些打算

30岁之前储备弹药

每个人喜欢的type不一样

现在不努力其实在给未来设限

comquter science

做一些research

技术党,可以在技术上一直钻研下去

怎么样去balance生活和工作

常见的问题:
1.阈值:
2.负载因子:
3.为什么数组长度始终要保持2的次幂
4.

JDK7 - :
1.数据结构:单纯的数组加链表
2.put操作:
3.resize操作:
4.阈值:
5.负载因子:

JDK8 - :
1.数据结构:数组加链表或者红黑树
2.put操作:
3.resize操作:
4.阈值:
5.负载因子:

扩容:

put: