for(elt <- bufferObject: scala.collection.mutable.Buffer)
// Do something with the element of the collection
以什么顺序访问for循环中的元素?随机?
从Scala API可以看出Buffer是Seq的子类,其中元素是有序的。这也适用于上面的循环吗?
答案 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
- 理解将会涉及map
,flatMap
和foreach
的某些组合,这些都遵循Seq
&# 39;定义的顺序。
答案 3 :(得分:1)
除非您使用并行集合(通过par
方法),否则可保证可变缓冲区中的操作顺序(如comprehension,map,foreach和其他顺序方法)。