我可以从Scala文档中看到scala.collection.immutable.Set只是一个特征。默认情况下使用Set实现中的哪一个? HashSet或TreeSet(或其他)?
我想了解/计划某些功能的运行时间。
示例:
scala> val s = Set(1,3,6,2,7,1)
res0: scala.collection.immutable.Set[Int] = Set(1, 6, 2, 7, 3)
s.find(5),O(1)或O(log(n))的运行时间是什么?
由于同样适用于Map,最好的解决方法是什么?
答案 0 :(得分:17)
通过查看源代码,您可以发现最多设置四个元素的优化实施由EmptySet
,Set1
,Set2
,Set3
和{ {1}},只保存单个值。
例如这里的Set4
声明(自scala 2.11.4起):
Set2
这是class Set2[A] private[collection] (elem1: A, elem2: A) extends AbstractSet[A] with Set[A] with Serializable
实施:
contains
或def contains(elem: A): Boolean =
elem == elem1 || elem == elem2
实施
find
非常直截了当。
对于包含4个以上元素的集合,底层实现为override def find(f: A => Boolean): Option[A] = {
if (f(elem1)) Some(elem1)
else if (f(elem2)) Some(elem2)
else None
}
。我们可以在REPL中轻松验证:
HashSet
话虽如此,scala> Set(1, 2, 3, 4).getClass
res1: Class[_ <: scala.collection.immutable.Set[Int]] = class scala.collection.immutable.Set$Set4
scala> Set(1, 2, 3, 4, 5, 6).getClass
res0: Class[_ <: scala.collection.immutable.Set[Int]] = class scala.collection.immutable.HashSet$HashTrieSet
必须始终遍历整个find
,因为它未分类,因此它将是HashSet
。
相反,O(n)
之类的查找操作将改为contains
。
Here's a more in-depth reference关于scala集合的性能。
说到O(1)
,几乎相同的概念适用。优化Map
实施最多4个元素,然后它是Map
。