为什么最多要订购4个元素的集合,而没有排序的元素呢?

zha*_*uan 2 scala set

给定

val xs1 = Set(3, 2, 1, 4, 5, 6, 7)
val ys1 = Set(7, 2, 1, 4, 5, 6, 3)
Run Code Online (Sandbox Code Playgroud)

xs1ys1这两个结果scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 4)

但较小的波纹管

val xt1 = Set(1, 2, 3)
val yt1 = Set(3, 2, 1)
Run Code Online (Sandbox Code Playgroud)

生产

xt1: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
yt1: scala.collection.immutable.Set[Int] = Set(3, 2, 1)
Run Code Online (Sandbox Code Playgroud)

为什么不订购前者而订购后者似乎呢?

Mar*_*lic 5

行为上的差异是由于对最多4个元素的集合进行优化

不可变集合的默认实现使用适合于集合中元素数量的表示形式。空集仅由一个单例对象表示。最多四个大小的集合由单个对象表示,该对象将所有元素存储为字段。超过该大小,不可变集被实现为压缩哈希数组映射的前缀树

本·詹姆斯Ben James)类似地解释:

Set也是带有apply **方法的伴侣对象*。当您调用Set(...)时,您将调用此工厂方法并获得某种Set的返回值。它可能是HashSet,但可能是其他一些实现。根据2,不可变集的默认实现对空集和集大小最大为4的特殊表示形式。大小不小于5的不可变集和可变集都使用hashSet。

由于的大小Set(3, 2, 1, 4, 5, 6, 7)大于4,因此其具体实现为HashSet

Set(3, 2, 1, 4, 5, 6, 7).getClass
class scala.collection.immutable.HashSet
Run Code Online (Sandbox Code Playgroud)

这并不能保证插入顺序。另一方面,Set(1, 2, 3)专用类的具体实现Set3

Set(1,2,3).getClass
class scala.collection.immutable.Set$Set3
Run Code Online (Sandbox Code Playgroud)

将三个元素存储在相应的三个字段中

final class Set3[A] private[collection] (elem1: A, elem2: A, elem3: A) extends AbstractSet[A] ...
Run Code Online (Sandbox Code Playgroud)