行为差异是由于优化 https://github.com/scala/scala/blob/a3791d4d61bd584f27e4dac8765f753a27bb95e0/src/library/scala/collection/immutable/Set.scala#L188对于套最多 4 个元素 https://docs.scala-lang.org/overviews/collections-2.13/sets.html
不可变集的默认实现使用表示
适应集合的元素数量。空集是
仅由一个单例对象表示。套尺寸最多为四个是
由将所有元素存储为字段的单个对象表示。
超出该大小,不可变集的实现方式为压缩的
哈希数组映射前缀树 https://docs.scala-lang.org/overviews/collections-2.13/concrete-immutable-collection-classes.html#compressed-hash-array-mapped-prefix-trees.
类似地解释为本·詹姆斯 https://stackoverflow.com/a/7018941/5205022:
Set 也是一个带有 apply** 方法的伴随对象*。你打电话时
Set(...),您正在调用此工厂方法并获得返回
value 是某种 Set。它可能是一个 HashSet,但也可能是
其他一些实现。根据2,默认实现
对于不可变集,对于空集和集合有特殊的表示
大小最大为 4。大小为 5 及以上的不可变集和可变集均使用
哈希集。
由于尺寸为Set(3, 2, 1, 4, 5, 6, 7)
大于4,则其具体实现为HashSet
Set(3, 2, 1, 4, 5, 6, 7).getClass
class scala.collection.immutable.HashSet
这确实not https://stackoverflow.com/a/5246204/5205022保证插入顺序。另一方面,具体落实Set(1, 2, 3)
是专门的班级Set3 https://github.com/scala/scala/blob/a3791d4d61bd584f27e4dac8765f753a27bb95e0/src/library/scala/collection/immutable/Set.scala#L190
Set(1,2,3).getClass
class scala.collection.immutable.Set$Set3
它将三个元素存储在对应的三个中fields
final class Set3[A] private[collection] (elem1: A, elem2: A, elem3: A) extends AbstractSet[A] ...