java - 哪个联合效率更高: List/HashSet

标签 java scala collections

我正在编写一些需要使用集合的算法,并且它们的主要(也是唯一)操作是并集。

我将拥有大约100万个对象,并且我需要知道哪个集合具有更有效的联合方法 - 列表或 HashSet(也许还有别的吗?)。

提前致谢。

最佳答案

我猜当你说“我将使用 distinct 与列表”时,你的意思是这样的:

  List l = ...
  Set result = Collectors.toSet(l.stream().distinct()).union(someOtherSet);

与此相比:

  HashSet h = ...
  Set result = h.union(someOtherSet);

显然第二个版本更有效。第一个必须从列表中生成一个中间集。每次运行它时。

第一个节省的唯一东西是一些内存(从长远来看),因为中间集在使用后变得无法访问。

第一个版本可以更简单、更有效地编写为:

  List l = ...
  Set result = new HashSet(l).union(someOtherSet);

List API 没有 distinct() 方法,也没有 union() 方法。


如果您实际上使用Collection.contains()来执行联合,那么HashSet()将比任何标准List快得多> 实现。正如 @JBNizet 所说:

HashSet.contains is O(1). List.contains is O(n).

例如:

  Set result = new HashSet();
  for (Integer element: set1) {
      if (set2.contains(element)) {
          result.add(element);
      }
  }
  // result now contains the union of set1 and set2.

几乎相同的代码适用于列表。但速度慢得多

你问:

Ok, yeah. But how about union?

见上文。这是关于使用 contains 调用实现 union

Whats that? O(?)

请参阅以下文章:

So the both of the unions are the same O(N) (n - size of the second collection)?

没有。

  • 使用 HashSet:N x O(1)O(N)
  • 使用列表:N x O(N)O(N^2)

或更准确地说:

  • 使用 HashSet:min(M, N) x O(1)O(min(M, N))
  • 使用列表:N x O(M)O(NM)

其中 N 和 M 是两个集合/列表的大小。您可以通过迭代两个集合中较小的一个来调整 HashSet 情况的性能。正如上面所反射(reflect)的。


最后,如果元素类型为 Integer,则 Bitset 可能比 ListHashSet 更高效。而且它可以使用少几个数量级的内存!取决于整数的范围以及集合的密度


这就是Java分析。我不熟悉 Scala,但底层计算和复杂性是相同的。

关于java - 哪个联合效率更高: List/HashSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46863211/

相关文章:

java - ArrayList不打印重复项(Java)

java - TextView dp 不随屏幕尺寸缩放

ScalaTest 规范编译错误

java - JPA/Hibernate + 从 onetomayrelation 获取特定项目

list - 如何从列表的元素创建所有可能的组合?

java - 在 Java 中,如何将 scala.list 转换为 java.list

java - 如何从列表<String>中删除重复元素?

java - 与 spring 集成 dsl 作斗争

Java JTextPane 没有收到击键

java - 如何创建这样的 Java swing UI?