偶然想到的HashMap 与 RandomAccess

无意中在RandomAccess接口里,看到JDK自带的说明有如下一段

It is recognized that the distinction between random and sequential access is often fuzzy. For example, some List implementations provide asymptotically linear access times if they get huge, but constant access times in practice.Such a List implementation should generally implement this interface. As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:
     for (int i=0, n=list.size(); i < n; i++)
         list.get(i);
runs faster than this loop:
     for (Iterator i=list.iterator(); i.hasNext(); )
         i.next();

这段话的意思,难道遍历List for 循环遍历 要比 get 更比Iterator 更快?
凭直觉应该是 Iterator 更快吧。
于是就有疑问了,说到随机访问的话,HashMap 应该更多地进行随机访问吧,可JDK 里偏偏 HashMap 没有实现 RandomAcess接口
继续查阅文档才发现,
HashMap 的 key-value 对 是以 Entry 的形式存储在一个数组中的。而数组本身其实实现了数组自身的 Random Access 逻辑。
顺便查看了HashMap 的源码,
1、HashMap 在用 key 找 value 时, 算出 key 的 hashcode 之后,用 key 的 hashcode 与 entrytable 的当前size 求  & 操作,找到对应的 index。
2、再用数组操作找到同 hashcode 的 Entry 链。(此处应当运用了数组自带的 random access)
3、在Entry 链中找到 与 key  == 或 equal 的 Entry返回 value
entry 的存储方式如下:

[entry, entry, entry, entry ,entry, null....]
         |
         .next
         |
         entry
         |
         .next
         |
         entry

当然这样的话,每次增加hashmap 容量时,就会重新分配数组,计算entry 位置,开销还是挺大的。

reeoo.com - web design inspiration

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注