HashMap与LinkedHashMap在值迭代中的性能()

MBZ*_*MBZ 27 java collections hashmap linkedhashmap

遍历功能HashMapLinkedHashMap遍历values()功能之间是否存在性能差异?

Aja*_*rge 39

我认为LinkedHashMap由于其优越的nextEntry实现,遍历必须更快Iterator

原因如下:

让我们从values实施步骤一步步走.
HashMap实施values是这样的:

   public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null ? vs : (values = new Values()));
    }
Run Code Online (Sandbox Code Playgroud)

LinkedHashMap 从扩展HashMap和继承相同的实现.

区别在于两者的Iterator实施Values.

因为HashMap它延伸自 java.util.HashMap.HashIterator

  private final class ValueIterator extends HashIterator<V> {
        public V next() {
            return nextEntry().value;
        }
    }
Run Code Online (Sandbox Code Playgroud)

LinkedHashMap它延伸自java.util.LinkedHashMap.LinkedHashIterator

 private class ValueIterator extends LinkedHashIterator<V> {
        public V next() { return nextEntry().value; }
    }
Run Code Online (Sandbox Code Playgroud)

所以差异基本上归结为nextEntry实施.

因为LinkedHashMap它只是调用e.after,其中e是Entry,但是因为HashMap有一些工作涉及遍历Entry[]数组以找到下一个.

UPDATE:用于nextEntry()HashMap

final Entry<K,V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            Entry<K,V> e = next;
            if (e == null)
                throw new NoSuchElementException();

            if ((next = e.next) == null) {
                Entry[] t = table;
                while (index < t.length && (next = t[index++]) == null)
                    ;
            }
            current = e;
            return e;
        }
Run Code Online (Sandbox Code Playgroud)

Entry []不是连续的商店.(两者之间可能存在空值).如果您查看上面的代码,它的作用是指向current旁边,并通过迭代Entry []找到下一个代码.

我认为这种性能提升将以插入成本为代价.查看addEntry两个类中的方法作为练习.


use*_*765 38

我写了一个小的分析程序,创建了100万个键(Integer)和Boolean.TRUE,重复了100次.找到以下内容:

HashMap:-
Create:  3.7sec
Iterate: 1.1sec
Access:  1.5sec
Total:   6.2sec

LinkedHashMap:-
Create:  4.7sec   (30% slower)
Iterate: 0.5sec   (50% faster)
Access:  0.8sec   (50% faster)
Total :  6.0sec
Run Code Online (Sandbox Code Playgroud)

垃圾收集没有这样做有点污染数字,但我认为LinkedHashMap优于HashMap,我将在未来的代码中使用它.

  • 我认为你的测试不正确并且没有正确完成 (5认同)
  • 对于迭代,特别是考虑到上述评论是有道理的,但我不清楚使用“LinkedHashMap”如何更快地访问。对我来说,`LinkedHashMap` 的`get(Object key)` 函数与`HashMap` 的`get(Object key)` 函数做了什么相同的事情,并检查了一个`afterNodeAccess()` 函数,这对我来说毫无意义在返回结果之前会有更快的性能。 (2认同)

Ale*_*exR 5

几乎没有关系。问题是:您需要什么。如果元素的顺序相关,则必须使用LinkedHashMap。否则,您只是不需要它,请使用HashMap