Scala Map 中的 take 函数是否定义明确?

Is the take function well defined on a Scala Map?

在 Scala Map 上使用 take 函数安全吗?我认为 Map 是无序的,因此 myMap.take(2) 会 return 2 个 myMap 的随机元素。但是在解释器上测试让我觉得是安全的:

scala> val z = Map(1 -> 10, 2 -> 20, 3 -> 30, 4 -> 40)
z: scala.collection.immutable.Map[Int,Int] = Map(1 -> 10, 2 -> 20, 3 -> 30, 4 -> 40)

scala> z.take(2)
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 10, 2 -> 20)

scala> z.take(2)
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 10, 2 -> 20)

scala> z.take(2)
res3: scala.collection.immutable.Map[Int,Int] = Map(1 -> 10, 2 -> 20)

scala> z.take(2)
res4: scala.collection.immutable.Map[Int,Int] = Map(1 -> 10, 2 -> 20)

那么,在 Map 上使用 take 安全吗?还是我需要使用 ListMap

您每次 take(2) 很可能会得到相同的 2,但不知道您首先会得到哪 2。

val y = Map(1 -> 10, 2 -> 20, 3 -> 30, 4 -> 40, 5 -> 5)
y.take(2)  //res0: Map[Int,Int] = Map(5 -> 5, 1 -> 10)

在不知道您想要实现什么的情况下,您可能需要考虑使用 SortedMap,它可以保证键按顺序排序。考虑 Scala REPL 中的以下两个示例:

scala> val z = Map(4 -> 40, 3 -> 30, 1 -> 10, 2 -> 20)
z: scala.collection.immutable.Map[Int,Int] = Map(4 -> 40, 3 -> 30, 1 -> 10, 2 -> 20)

scala> z.take(2)
res0: scala.collection.immutable.Map[Int,Int] = Map(4 -> 40, 3 -> 30)

scala> import scala.collection.immutable.SortedMap
import scala.collection.immutable.SortedMap

scala> val zs = SortedMap(4 -> 40, 3 -> 30, 1 -> 10, 2 -> 20)
zs: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 10, 2 -> 20, 3 -> 30, 4 -> 40)

scala> zs.take(2)
res1: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 10, 2 -> 20)

正如@jwvh 指出的那样,在常规 Map 中没有定义的顺序,但是一旦定义该顺序就固定了,因此您总是会为 .take(2) 返回相同的成员给定相同的地图实例。但是,返回哪些值取决于地图的创建顺序。

同时,在 SortedMap 中,键始终是有序的,因此当您使用 .take(2) 元素时,无论定义顺序如何,您将始终获得相同的两个元素:那些有两个最低键值。

请参阅 help on the take method 了解更多信息。

Scala 中的不可变映射具有用于 0 到 4 个元素的特殊子类型,you can see in the code 作为一种优化。碰巧的是,最多有 4 个参数的 Map.apply 会生成其中一个 类 的实例,因此迭代它将始终按照传递给 Map.apply.

的顺序生成元素

Is the take function well defined on a Scala Map?

这取决于您对 "well-defined" 的确切定义,但我认为,是的,对于 "well-defined" 的大多数常见解释,它是明确定义的。

The documentation清楚地列出了所有可能输入的所有可能结果,并且没有模棱两可或未指定的输入。涵盖所有极端情况:

  • 如果集合少于 n 个元素,将返回整个集合。
  • 如果n为负数,将返回一个空集合。
  • 如果集合是无序的,将返回任意元素。

Is the take function safe to use on a Scala Map?

这取决于您对 "safe" 的确切定义,但我认为,是的,对于 "safe" 的大多数常见解释,它是安全的。

  • 它是静态类型安全的。
  • 它是动态类型安全的。
  • 它不会抛出异常。

I thought that Maps were unordered, so that myMap.take(2) would return 2 random elements of myMap.

没有。文档说:

Note: might return different results for different runs, unless the underlying collection type is ordered.

这意味着将返回任意元素,而不是随机元素。