简述:解释HashMap
HashMap分为以下部分
table:是数组,用来标记顺序的
slot:是哈希槽,对应数组下标
bucket:是哈希桶,存储键值对(JDK8中加入红黑树,如果存储的链表长度大于8时,会将链表转化成红黑树进行存储)
HashMap存在的问题
1.数据丢失 在JDK7中并发赋值时会被覆盖
在源码中,需要把新添加的元素直接放在slot槽中,可以使新添加的元素在下次提取时更快的被访问到
例如:
table[bucketIndex]=new Entery<>(hash,key,value,e);
如果两个线程同时执行到第一处,其中一个线程会被后来的执行的线程所覆盖,从而造成对象化丢失。
2.新表被覆盖
3.已遍历区间再新增元素会丢失
4.迁移丢失:在迁移过程中,有并发时,next被前置成null
重写equals方法必须重写hashcode吗
一般的地方不需要重载hashcode,只有当类放在HashTable,HashMap,HashSet等Hash结构的集合时,才会重载hashcode
hashcode方法用来定义索引位置,以提高效率的同时可能会发生效率冲突,当出现hash冲突时,我们就得通过equals()方法来判断冲突的对象是否相等
如果只重写hashcode方法,当发生hash冲突时,即使两个对象相等,也不会判断为重复,进而导致数组里会重写一大堆重复对象
如果只重写equals方法,那两个相等的对象,内存地址未必相等,这样也会造成重复元素的问题,所以需要同时重写
hashcode方法用来在最快时间内,判断两个对象是否相等。
equals方法用来判断两个对象是否绝对相等
hashcode方法用来保证性能,equals方法用来减少误差
JDK81.8之后,HashMap加入红黑树
当一个桶存储链表的长度大于8时,将会使用红黑树代替链表进行存储