在for循环中以哪种顺序访问Scala Buffer的元素?

时间:2012-06-06 20:42:53

标签: scala

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

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

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

4 个答案:

答案 0 :(得分: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上可用的方法(或者您拥有的任何其他类型),因此集合提供的保证全部应用。请注意,例如,与GenSeq一起使用的map(for-yield)可以并行处理所有元素,但会生成newCollection(i) == makeSomething(bufferObject(i))的集合,即保留索引

答案 1 :(得分: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

答案 2 :(得分:1)

是的,for - 理解将会涉及mapflatMapforeach的某些组合,这些都遵循Seq&# 39;定义的顺序。

答案 3 :(得分:1)

除非您使用并行集合(通过par方法),否则可保证可变缓冲区中的操作顺序(如comprehension,map,foreach和其他顺序方法)。