我正在写一些需要使用集合的algorithem,而且它们的主要(也是唯一)动作是union。
我将拥有 100万个对象,我需要知道哪个集合具有更高效的union方法 - 列表或HashSet (不可能)别的什么?)。
提前致谢。
答案 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 - 第二个集合的大小)?
没有。
N x O(1)
为O(N)
N x O(N)
为O(N^2)
或者更确切地说:
min(M, N) x O(1)
为O(min(M, N))
N x O(M)
为O(NM)
其中N和M是两组/列表的大小。您可以通过迭代两个中较小的一组来调整HashSet
案例的性能。如上所述。
最后,如果元素类型为Integer
,那么Bitset
可能比List
或HashSet
更有效。它可以使用几个数量级的内存!取决于整数的范围,以及集合的密度。
这是Java分析。我不熟悉Scala,但基础计算和复杂性将是相同的。