HashMap相关


源码解析

1.8源码解析

1.7源码解析

对比
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()方法。作为不可变类天生是线程安全的,