哪个联合更有效:List / HashSet

时间:2017-10-21 12:28:33

标签: java scala collections

我正在写一些需要使用集合的algorithem,而且它们的主要(也是唯一)动作是union。

我将拥有 100万个对象,我需要知道哪个集合具有更高效的union方法 - 列表或HashSet (不可能)别的什么?)。

提前致谢。

1 个答案:

答案 0 :(得分:2)

我猜测当你说'#34;我将distinct与List"一起使用时,你的意思是这样的:

  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是O(1)。 List.contains是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.

几乎相同的代码适用于列表。但它很多更慢。

你问:

  

好的,是的。但是工会呢?

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

  是什么意思? O(?)

请参阅以下文章:

  

所以这两个联合都是相同的O(N)(n - 第二个集合的大小)?

没有。

  • 使用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案例的性能。如上所述。

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

这是Java分析。我不熟悉Scala,但基础计算和复杂性将是相同的。