繁体   English   中英

HashMap或TreeMap或LinkedHashMap哪一个迭代最快?

[英]HashMap or TreeMap or LinkedHashMap which one is fastest to iterate over?

我有一张Map ,它在应用程序启动时填满。 在执行应用程序期间,它不会在以后更改。 之后,此映射仅用于迭代其中的所有元素。 我应该选择哪种具体的Map实现? HashMapTreeMapLinkedHashMap
UPDATE
广告订单无关紧要。 唯一重要的是快速迭代所有元素(比如6000个元素)。

HashMap通常是最快的,因为它具有最佳的缓存行为( HashMap直接在后备数组上迭代,而TreeMapLinkedHashMap迭代链接的数据结构)。

如果地图初始化后不会改变,您可能希望使用ImmutableMapUnmodifiableMap

这里没有其他答案考虑到CPU缓存的影响,当涉及迭代时,这可能是巨大的

改善这种情况的一种方法是仅使用单个交错键和值数组(偶数索引处的键,奇数处的值)。 这将紧密地将这些数据项组合在一起并最大限度地利用缓存,至少对于引用而言。

但是,如果您可以避免创建保存数据的对象并仅使用原始值数组,那么将实现真正的,尖锐的改进。 当然,这很大程度上取决于您的使用案例。

我不会使用地图。 如果你想要的只是遍历条目,那么创建一个你需要的新的ArrayList并使用它 - 你不能比ArrayList更快地进行迭代。

// Which map you use only chooses the order of the list.
Map<Key,Value> map = new HashMap<>();
// The list to iterate for maximum speed.
List<Map.Entry<Key,Value>> list = new ArrayList<>(map.entrySet());

这样,您只需遍历条目集一次即可构建列表。 从那时起,你一次又一次地遍历列表 - 这当然应该接近最优。

注意在Marko的建议下从LinkedList更改为ArrayList

如果您的地图仅用于迭代元素并且迭代速度很重要,那么将地图转换为ArrayList并迭代它,这将是最快的方法。

我同意以星-樟木的回答,并补充一句:如果你需要在迭代过程中同时访问 ,最快的方法是使用entrySet()方法,如讨论在这里

现在,如果您确定地图永远不会改变,为什么不使用单独的数据结构进行迭代? 例如:在完成的地图上迭代一次,并在相同的相应位置填充其内容的几个数组,一个带有键,另一个带有值。 然后遍历这些数组将尽可能快。

从Java 10开始,您可以使用Map.of()重载方法之一或Map.copyOf()来创建不可修改的Map 由于这些方法返回的映射不支持将任何新条目放入映射中,因此现有的键/值以交错模式存储,如本答案中所述 这应该为您的用例提供最佳性能。

Map.forEach(BiConsumer)几乎总是比迭代器更快,有时候很大。 如果您要对值进行求和,例如:

public class TestForStackOverflow {
    int sum = 0;

    // Or whatever Map you are using
    Map<Object, Integer> map = new HashMap();

    static class C implements BiConsumer<Object, Integer> {
        int sum = 0;

        @Override
        public void accept(Object k, Integer v) {
            sum += v;
        }
    }

    public int getSum(Map map) {
        C c = new C();
        map.forEach(c);
        return c.sum;
    }

    public int getSum2(Map map) {
        map.forEach((k, v) -> sum += v);
        return sum;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM