下面是改编自Scala在线教程的一小段代码:
object Test {
def main(args: Array[String]) {
val fruit1 = List("apples", "oranges", "pears")
val fruit2 = List("mangoes", "banana")
val veg1 = Set("potatoes", "carrots", "peas")
val veg2 = Set("cabbage", "squash")
var fruit = fruit1 ++ fruit2
println( "fruit1 ++ fruit2 : " + fruit )
var vegetable = veg1 ++ veg2
println( "veg1 ++ veg2 : " + vegetable )
}
}结果如下:
fruit1 ++ fruit2 :列表(苹果、橙子、梨、芒果、香蕉)
veg1 ++ veg2 :套餐(卷心菜,豌豆,南瓜,胡萝卜,土豆)
列表连接的工作方式与我预期的一样,但我永远无法预测到集合连接的结果顺序。有人能解释一下结果是如何得出的吗?在线教程在这里没有多大帮助。
发布于 2015-11-21 03:25:57
scala.collection.Set不提供任何关于遍历顺序的保证--如果你要求一个字符串表示,你得到的顺序是未指定的,并且取决于实现。
scala.collection.Set的一些子类确实提供了有关顺序的保证-例如,在迭代collection.immutable.SortedSet时看到的顺序将取决于您用来构造集合的Ordering实例,而collection.mutable.LinkedHashSet将按插入顺序迭代其元素。但是,当您使用任意Set时,您永远不应该依赖于您在使用toString、foreach等时碰巧看到的顺序。
发布于 2015-11-21 03:35:42
请注意,由于Set是一种无序数据结构,因此实现可以随意使用任意顺序。
Set的默认实现在幕后使用HashSet。这是使用散列方法实现的,该方法使O(n)确定项目是否存在于集合中。输出的顺序可能是每个项目生成的散列的顺序,这实际上是随机的。
另一种实现是TreeSet,它以树的形式存储数据,因此是O(log(n)),用于确定集合中是否存在项目。在这种情况下,输出顺序是项在树中的顺序。
下面的代码演示了这一点:
import scala.collection.immutable.{TreeSet, HashSet}
val veg1 = HashSet("potatoes", "carrots", "peas")
val veg2 = HashSet("cabbage", "squash")
val vegetable = veg1 ++ veg2
println( "veg1 ++ veg2 : " + vegetable )
//veg1 ++ veg2 : Set(cabbage, peas, squash, carrots, potatoes)
val trVeg1 = TreeSet("potatoes", "carrots", "peas")
val trVeg2 = TreeSet("cabbage", "squash")
val trVegetable = trVeg1 ++ trVeg2
println( "trVeg1 ++ trVeg2 : " + trVegetable )
//trVeg1 ++ trVeg2 : TreeSet(cabbage, carrots, peas, potatoes, squash)编辑:
正如Travis Brown在评论中指出的那样,Set的“默认实现”是一个HashSet,这并不完全正确。当项目数量很少时,Scala有特定的Set实现,但是当创建一个超过4个项目的集合时,或者当在Set()实例上使用++运算符创建超过4个项目的Set时,结果是一个HashSet:
val set1 = Set("abc", "def", "ghi")
val set2 = Set("abcd", "defg", "ghij")
set1.getClass
//scala.collection.immutable.Set$Set3
set2.getClass
//scala.collection.immutable.Set$Set3
val concSet = set1 ++ set2
concSet.getClass
//scala.collection.immutable.HashSet$HashTrieSet小集合实现只有4个项目的集合,所以:
val set3 = Set("abcd", "defg", "ghij", "fghtre", "dfghdd")
set3.getClass
//scala.collection.immutable.HashSet$HashTrieSethttps://github.com/scala/scala/blob/2.12.x/src/library/scala/collection/immutable/Set.scala#L184
https://stackoverflow.com/questions/33834304
复制相似问题