源码解析
1.8源码解析
https://www.cnblogs.com/xiaoxi/p/7233201.html
1.7源码解析
https://www.cnblogs.com/better-farther-world2099/p/9258605.html
对比
https://blog.csdn.net/weixin_44141495/article/details/108402128
JDK 1.7到1.8有什么优化
resize 扩容优化,不用rehash,快速寻址
引入了红黑树,目的是避免单条链表过长而影响查询效率
解决了resize时多线程死循环问题,但仍是非线程安全的
Hash 算法做了哪些优化
hash右移16位再异或,使高位也参与hash,据说减少碰撞
头插法有什么问题
JDK1.7时使用的是头插法,同一位置上新元素总会被放在链表的头部位置,所以在多线程的情况下有可能会产生环形链表。JDK1.8之后使用尾插法,在扩容时会保持链表元素原本的顺序,就不会出现环形链表的问题。
什么时候扩容,0.75,扩容步骤,为什么分高低位
元素数量大于阈值
时间和空间成本的权衡,0.75时,链表长度大于8是个小概率事件,原理是泊松分布;
扩容步骤,新建数组,长度为2倍,将原来元素复制到新数组,一个链表按顺序分成两个链表,低位链表在原位置,高位链表的位置在原来基础上加上原容量大小
分高低位可以减少冲突,减少链表长度
平时在使用HashMap时一般使用什么类型的元素作为Key?
选择Integer,String这种不可变的类型,像对String的一切操作都是新建一个String对象,对新的对象进行拼接分割等,这些类已经很规范的覆写了hashCode()以及equals()方法。作为不可变类天生是线程安全的,