HashMap 在 jdk 1.7 中为什么选的头插法,而不是尾插法

2021 年 1 月 12 日
 DengDDDD

在我看来,头插法和尾插法都要遍历一遍链表啊,应该不是效率问题吧.

4418 次点击
所在节点    Java
12 条回复
VincentWang
2021 年 1 月 12 日
有一种说法是:缓存的时间局部性原则 (新插入的数据可能会更早用到)
DengDDDD
2021 年 1 月 12 日
我刚看了遍源码,得出一个结论,感觉还挺像的
插入时需要判断是否重复,此时要遍历一遍链表,
如果采用尾插法,需要将尾节点保存起来,传入后面的 addEntry 的方法中
addEntry 会判断是否需要扩容,如果扩容的话,待插入节点的下标就需要重新计算,
这样之前保存的尾节点就不一定正确,需要在重新计算一次尾节点,
所以说使用头插法效率会高一些
DengDDDD
2021 年 1 月 12 日
@VincentWang 刚刚不知道如何回复。
qwerthhusn
2021 年 1 月 12 日
插头插尾都无所谓,因为链表长度达到 8 (好像是 6,忘记了)的时候,就变成红黑树了,
长度个位数的链表,咋遍历都不会影响性能
kx5d62Jn1J9MjoXP
2021 年 1 月 12 日
因为简单啊,怎么简单怎么来呗
emSaVya
2021 年 1 月 12 日
头插有概率形成死循环 1.8 以后改成尾插
cco
2021 年 1 月 13 日
@qwerthhusn 这不是 1.8 后才有的么?
DengDDDD
2021 年 1 月 13 日
@qwerthhusn,在 1.8 之后确实不用考虑这个问题了,但是我当时奇怪的是 1.7 为什么用的头插法。
@emSaVya 对,就是因为头插法会形成环形链表,所以我才好奇为什么不用尾插法,当时我以为效率一样,后面发现其实是不一样的。
ffhigh
2021 年 1 月 13 日
如果 1.7 只改尾插, 不改扩容机制。 也不会形成环么?
qifeng7
2021 年 1 月 15 日
可能是在扩容迁移元素的过程中,用头插法更快
qifeng7
2021 年 1 月 15 日
1.7 是一个元素一个元素迁移的,用尾插法就要遍历到链表尾部再插入
qifeng7
2021 年 1 月 15 日
扩容转移元素不需要遍历一遍链表哦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/744296

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX