【问题标题】:HashMap vs ArrayList performance am I correctHashMap vs ArrayList 性能我是正确的
【发布时间】:2010-12-03 20:05:33
【问题描述】:

我目前认为:

  • 当您需要一个从中随机检索项目的结构时 - 使用 HashMap
  • 当您按顺序检索项目时(例如,使用 for 循环) - 使用 ArrayList

我通常是正确的吗?是否存在不正确的情况?

【问题讨论】:

    标签: java performance arraylist hashmap


    【解决方案1】:

    地图是map, or "associative array"。它具有键-> 值布局。另一方面,List 是 list,它是元素的有序集合。

    Set 和 List 之间可能会进行更直接的比较:两者都保存值,其中列表是明确排序的(您可以获得元素 #x),而集合(通常)不是已排序(好吧,除非它是 SortedSet,在这种情况下迭代顺序将由比较器排序)。

    Set 和 List 最常见的两种实现是 HashSet 和 ArrayList。要检查一个元素是否属于数组列表(contains(element)),实现会遍历它的所有元素,检查是否使用 equals() 方法找到了该元素。要检查一个元素是否属于 hashset,首先计算元素的 hashCode(),然后“直接”到该元素 应该所在的位置,并检查它是否存在。

    因此,ArrayList 和 HashSet 的一个显着区别在于 contains() 的速度

    在列表中,除了可以对集合执行的操作(添加、删除、询问是否存在(包含)和迭代所有元素)之外,您还可以请求元素#x。

    在地图上,您可以通过键来请求元素,而不是像使用列表那样通过索引。

    HashSet 目前仅由 HashMap 实现,其中不使用 key->value 关系的 value 部分。这是完全荒谬的,除了为插入 HashSet 中的每个和所有元素浪费至少 4 个字节(可以争论 12 个字节)之外没有任何用处。

    【讨论】:

    • HashSets 我曾经使用过一次或两次来维护一组元素,它们的源不能保证是不同的和唯一的(即,数据流中可能有重复的条目。)使用一个哈希集,你可以保证没有重复(被授予的等号和哈希码被正确实现。)大概这比在 List 中测试每个插入操作都包含一个给定的条目更优化。
    【解决方案2】:

    一般来说,是的,你是对的。还有一个组合数据结构LinkedHashMap,它提供对任意元素的快速访问以及可预测的排序。

    然而,值得注意的是,ArrayList 和 HashMap 分别只是 List 和 Map 接口的两种实现。每个都有其他实现可能更适合更具体的要求。例如,对于某些排队/出列要求,LinkedList 可能比 ArrayList 提供更高的性能。

    【讨论】:

    • 同样值得注意的是,如果这些集合要通过 JPA(或类似 Hibernate 的 ORM)持久化到数据库,则不能轻易使用像 LinkedHashMap 这样有用的替代实现,因为在哪些 ORM 重构了集合。
    【解决方案3】:

    我会说您通常是正确的,但并不完全准确。您使用HashMap 进行数据检索,但并不总是随机的。您可以使用 ArrayList 进行迭代,但您也可以使用它通过索引进行查找。

    更一般地,当您需要通过查找有效地检索项目时,您使用Map 实现,即根据键检索某些内容 - 例如字典、缓存、存储库等。

    当您只需要一个可以迭代数据的数据结构时,您可以使用List 实现,通常是当您希望它们以预定和/或可预测的顺序进行时。

    换句话说,您使用Maps 作为索引数据结构,并像通常使用数组一样使用Lists。

    【讨论】:

    • 我怀疑链表会给你更好的性能。数组访问是 O(1),就像单个链接遍历一样,但我希望数组的引用局部性更好,给你更好的结果。
    • LinkedList 在迭代性能方面并不明显优于 ArrayList。 (而且它肯定会使用更多内存!)。但对于某些类型的列表插入和删除操作,它明显更好。
    • 是的,我同意插入/删除对LinkedList 更好,尤其是在用作Deque 时。我的 cmets 是对“纯粹的迭代性能......”的回应。
    • 是的,你是对的。我将它与插入和删除的性能混淆了。
    【解决方案4】:

    不要忘记,使用地图(如果您有键)获取一个特定项目也比从数组中获取要快得多(除非您有索引,但键总能为您提供正确的值而如果插入新元素或删除旧元素,则索引可能不起作用)。

    【讨论】:

      【解决方案5】:

      对我来说,更关心的是我是否关心集合中项目的排序。如果您确实关心订单,请使用 ArrayList。如果您不关心订单(您只想存储一堆项目),那么您可以使用 HashMap。

      【讨论】:

        【解决方案6】:

        我有点不同意。对我来说,这更多地取决于我想如何检索这些项目。如果我想根据它们的顺序(准确地说是按索引)这样做,我会倾向于使用像 ArrayList(甚至是数组)这样的线性结构。如果我需要查找项目,我会使用 HashMap 之类的映射结构。

        正如 dan 指出的,另一个复杂的因素与插入和顺序有关。

        【讨论】:

          猜你喜欢
          • 2011-01-25
          • 2015-06-17
          • 1970-01-01
          • 2016-03-16
          • 1970-01-01
          • 1970-01-01
          • 2013-01-27
          • 2021-04-17
          • 1970-01-01
          相关资源
          最近更新 更多