【问题标题】:Search a Map versus a List搜索地图与列表
【发布时间】:2016-09-04 11:01:54
【问题描述】:

我有一个关于效率的问题。

假设我有一个简单对象的列表Foo

public class Foo {
    Integer id;
    List<String> data;
    ...
}

现在我有一个 foo 类的列表

List<Foo> fooList = new ArrayList<Foo>();

假设我有数千条记录的集合,我需要将它们添加到此列表中,但是当我遇到已添加到列表中的 id 时,我需要附加 foo.data 列表而不是添加新的具有重复 ID 的 foo。

为我遇到的每个唯一 foo.id 创建一个映射是否明智

Map<Integer, Foo> uniqueFoos = new HashMap<Integer, Foo>();

当我遍历我的数千条记录时,我只需在地图上执行检查以查看 foo.id 是否已经存在

if(uniqueFoos.containes(record.id))
    uniqueFoos.getFoo().add(record.data)

else
    uniqueFoos.add(record.id, record)

一旦我将所有记录添加到地图中,我就会遍历地图并将每个 Foos 添加到列表中

for(Foos f: uniqueFoos)
    fooList.add(fooInMap.get(f))

或者我应该一起放弃Map 的想法。遍历fooList 并搜索它是否已经包含与record.id 匹配的foo.id 会更有效吗?或者甚至可以使用ArrayList.contains(...) 方法?我觉得这样做比使用地图方式效率低得多。

更新:有些人也提到了使用 Set。那么 Set 是否是遍历所有其他列出的选项的方法?

注意:我这里写的代码只是伪代码。

【问题讨论】:

  • 为什么不使用Set?
  • 你对'foo'对象中的ID值做了什么?您可以只使用地图,键入 ID,然后将您的值设为字符串列表吗?
  • @keppil 我研究过套装,但老实说我从未使用过套装。我现在正在阅读它。非常有趣的建议。
  • 当你需要一个没有重复的集合时,你应该考虑使用Set。请记住使用 Foo 等自定义对象覆盖 hashcode() 和 equals() 方法。
  • @keppil Set 会比 Map 快吗?

标签: java performance list dictionary


【解决方案1】:

HashMap 绝对是更好的选择。它会在 O(1) 中进行查找,而 List 是 O(n)。

因此,如果您需要查找和修改单个元素,通常使用 HashMap。

【讨论】:

    【解决方案2】:

    如果不分析您的代码,就很难确定。但是,哈希映射的随机访问需要固定的时间(大多数时候 - 如果没有冲突),而对数组的迭代始终是线性的。

    【讨论】:

      【解决方案3】:

      当您有“数千条记录”时,您绝对应该使用Map。

      您的示例 uniqueFoos.getFoo().add(record.data) 无法编译。
      应该是uniqueFoos.get(record.id).add(record.data)。

      为防止在地图中重复查找,您的代码应为:

      Foo foo = uniqueFoos.get(record.id);
      if (foo == null) // not found
          uniqueFoos.add(record.id, record);
      else
          foo.add(record.data);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-14
        • 1970-01-01
        • 1970-01-01
        • 2019-02-11
        • 1970-01-01
        • 2012-01-10
        • 2021-11-17
        • 1970-01-01
        相关资源
        最近更新 更多