【问题标题】:Most efficient way to check if row exists in grid Java检查网格Java中是否存在行的最有效方法
【发布时间】:2011-12-10 01:54:36
【问题描述】:

全部,

我想知道检查 List> 中是否已存在行的最有效方法是什么。 Foo 对象具有键/值对(以及不适用于此问题的其他字段)。列表中的每个集合都是唯一的。

举个例子:

List[
 Set<Foo>[Foo_Key:A, Foo_Value:1][Foo_Key:B, Foo_Value:3][Foo_Key:C, Foo_Value:4]
 Set<Foo>[Foo_Key:A, Foo_Value:1][Foo_Key:B, Foo_Value:2][Foo_Key:C, Foo_Value:4]
 Set<Foo>[Foo_Key:A, Foo_Value:1][Foo_Key:B, Foo_Value:3][Foo_Key:C, Foo_Value:3]
]

我希望能够检查列表中是否存在新的 Set(例如:Set[Foo_Key:A, Foo_Value:1][Foo_Key:B, Foo_Value:3][Foo_Key:C, Foo_Value:4]) .

每个 Set 可以包含 1-20 个 Foo 对象。该列表可以包含 1-100,000 个集合。不保证 Foo 在每个 Set 中的顺序相同(因此必须以某种方式对它们进行预排序以获得正确的顺序,例如 TreeSet)

想法 1:将其转换为矩阵是否更有意义?每列将是 Foo_Key 并且每一行将包含 Foo_Value? 例如:

A B C
-----
1 3 4
1 2 4
1 3 3

然后查找包含新值的行?

想法 2:创建每个 Set 的哈希,然后将其与新 Set 的哈希进行比较是否更有意义?

有没有我没有想到的更有效的方法?

谢谢

【问题讨论】:

  • 您的想法 2 是如果您使用 LinkedHashSet 而不是 List(并且只是称为 contains(newSet))会发生什么。它确实可能比 List.contains 调用更快,但您必须确保集合及其元素一旦添加到 LinkedHashSet,就永远不会被修改。

标签: java grid contains


【解决方案1】:

我建议您使用不那么奇怪的数据结构。至于寻找东西:通常哈希或排序+二进制搜索或树是要走的路,具体取决于您期望的插入/删除量。阅读有关基本数据结构和算法的书,而不是尝试重新发明轮子。

最后:如果这不是一个纯粹的学术问题,请遍历列表并进行比较。最有可能的是,这是可以接受的快。即使是 100,000 个条目也需要不到一秒钟的时间,因此在 99% 的所有用例中都无关紧要。

我喜欢引用 Knuth 的话:过早的优化是万恶之源。

【讨论】:

  • 不幸的是,db/java 对象就是这样设计的,这是一个不正常的特殊用例。我假设从长远来看,每行创建一个哈希会更快,但正如你所说,如果 for 循环有效,我不想重新发明轮子。我会试一试,看看效果如何。
【解决方案2】:

如果您将TreeSets 用于您的Sets,您不能只使用list.contains(set),因为TreeSet 将处理equals 检查吗?

另外,考虑使用 Guava 的 MultSet 类。Multiset

【讨论】:

  • 我认为我无法做到。每个 Foo 包含其他字段,这些字段可能不会使 Foo 相等(键/值相同,但其他字段不一样)。我不能覆盖等号,因为在其他地方进行比较需要其他字段。我猜这迫使我迭代它们并直接使用自定义哈希做一些事情......?
  • 我认为你正面临一个更大的问题......无论你在 equals 中定义了什么,Set 都将使用它来强制执行一次在 Set 中存在一个实例的情况。如果有两个“相等”的概念,而非标准的(一个是“等于”)没有用于 Set 的目的,那么 Set 将不起作用。
  • 正确。我打算遍历每个集合的键/值,并创建一个包含整个集合的哈希
  • 这不是我的意思。 Set 通常对 hashCode / equals 合约进行操作。如果您希望 Set 充当 Set,那么您需要为 Set 适当地实现 hashCode / equals。否则,您应该使用ListLists
  • 我想我会有一个唯一哈希的列表。当我得到一个新的 Foo 时,我会以同样的方式创建一个哈希,并对照现有的 Foo 列表检查它。这是“更快”,因为您不必多次循环遍历所有 Set 数据,但是构建哈希值很重要,正如 Kdansky 下面提到的,如果循环足够快,可能不值得
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2020-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多