1
for(elt <- bufferObject: scala.collection.mutable.Buffer)
  // Do something with the element of the collection

将按什么顺序访问 for 循环中的元素?随机?

从 Scala API 可以看出 Buffer 是 Seq 的子类,其中的元素是有序的。这也适用于上面的循环吗?

4

4 回答 4

7

以下是 的超类型的选择mutable.Buffer[A],以及它们提供的遍历保证:

  • Seq[A]-- 所有元素都有一个位置,有一个关联的索引;它们总是从最低索引到最高索引一一遍历。
  • GenSeq[A]-- 所有元素都有一个位置,有一个关联的索引;它们可以一个一个地遍历,也可以并行遍历;如果生成了新的集合,那么新集合中元素的位置将与旧集合相对应,即使是并行遍历。
  • Iterable[A]-- 元素可以以任意顺序遍历,但总是以相同的顺序遍历(即不能从一个迭代更改为另一个);它们将被一一遍历。
  • GenIterable[A]-- 元素可以以任意顺序遍历,但总是以相同的顺序遍历(即不能从一个迭代更改为另一个);遍历可以一个一个地发生,也可以并行地发生;如果生成了新的集合,那么新集合中元素的位置将与旧集合相对应,即使是并行遍历。
  • Traversable[A]-- 与 相同的保证Iterable[A],但有额外的限制,即您可以中断遍历,但您无法确定何时选择下一个元素(您可以Iterable[A]通过Iterator生成
  • GenTraversable[A]-- 与 相同的保证GenIterable[A],但有额外的限制,即您可以中断遍历,但您无法确定何时选择下一个元素(您可以GenIterable[A]通过Iterator生成
  • TraversableOnce[A]-- 与 中的保证相同Traversable[A],但您可能无法多次遍历元素。
  • GenTraversableOnce[A]-- 与 中的保证相同GenTraversable[A],但您可能无法多次遍历元素。

现在,所有保证都适用,限制更少,这实际上意味着所说的一切都Seq[A]适用于mutable.Buffer[A].

现在,到 for 循环:

for(elt <- bufferObject: scala.collection.mutable.Buffer)
  doSomething(elt)

与以下内容相同:

bufferObject.foreach(elt => dosomething(elt))

for(elt <- bufferObject: scala.collection.mutable.Buffer)
yield makeSomething(elt)

与以下内容相同:

bufferObject.map(elt => makeSomething(elt))

事实上,所有 for变体都将被转换为可用的方法Buffer(或任何其他类型),因此集合提供的保证都适用。请注意,例如,GenSeqmap(for-yield) 一起使用的 a 可能会并行处理所有元素,但会生成一个集合,其中newCollection(i) == makeSomething(bufferObject(i))保留索引。

于 2012-06-06T23:07:11.603 回答
1

应该订购。Buffer默认为ArrayBuffer我相信。

scala> import scala.collection.mutable.Buffer
import scala.collection.mutable.Buffer

scala> val x = Buffer(1, 2, 3, 4, 5)
x: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)

scala> for (y <- x) println(y)
1
2
3
4
5
于 2012-06-06T20:49:14.703 回答
1

是的,for-comprehension 将 desugar 到 , 和 的某种组合,map并且这些都遵循' 定义的顺序。flatMapforeachSeq

于 2012-06-06T20:50:13.867 回答
1

除非您使用并行集合(通过par方法),否则可变 Buffer 中的操作顺序(如理解、映射、foreach 和其他顺序方法)是有保证的。

于 2012-06-06T21:01:26.010 回答