HashMap插入元素的过程:
1 首先计算key的hash值,然后根据table的长度进行取模,找到自己的index位置。
2 如果table[index]位置上没有其他元素,则直接插入,否则就发生了hash冲突。
hashmap解决hash冲突是采用链地址法,也就是说,当发生hash冲突后,会
遍历链表中每个元素,调用equals方法进行比较,如果相等则将旧的value替换为新的 value,如果遍历结束后,都没有相等的,则在链表头部插入。
问题来了,为什么要在链表头部插入呢?网上说是避免尾部遍历。。但是真的存在避免尾部遍历么?因为在插入元素时,会调用equals方法和每个元素进行比较,少不了遍历的过程,完全可以在遍历结束后在尾部进行插入,并不会多出额外的时间复杂度。
求大神解答啊。。谢谢啦
首先HashMap在解决hashcode相同的时候,选择了头部插入的链式结构,我觉得主要是为了提高效率:
1、你后插入的相同hashcode的对象,从理论上说,应该是最近要使用的概率最高,所以插入头部位置。就好像某些软件的最近使用列表,一定是按照你最近打开的顺序排序的,那么你一定会去打开最近使用的吗?不一定,只是从感性上推断最近使用的那个打开的效率最高,例如从我工作的情况来看,重复打开同一个Work文档的概率非常高。
2、我记得源码里,并没有提供尾部遍历的方法,都是通过next指向下一个对象,并且你也说了头部和尾部的遍历效率几乎是一样的,所以我觉得避免尾部遍历的说法有点说不过去。
我在想的是,是不是因为其他什么原因?如果放在尾部,会不会需要一个额外的变量来保存上一个非空的元素。。
在jdk1.8之前是插入头部的,在jdk1.8中是插入尾部的。
另外这是一个单链,只有后驱,没有前驱
https://www.cnblogs.com/java-jun-world2099/p/9258605.html
resize()的时候并不需要比较了,头插法就避免了尾部遍历
有味了