为什么 Seq.newBuilder 返回一个 ListBuffer? [英] Why is Seq.newBuilder returning a ListBuffer?
问题描述
看着
val sb = Seq.newBuilder[Int]
println(sb.getClass.getName)
sb += 1
sb += 2
val s = sb.result()
println(s.getClass.getName)
输出是
scala.collection.mutable.ListBuffer
scala.collection.immutable.$colon$colon
scala.collection.mutable.ListBuffer
scala.collection.immutable.$colon$colon
使用 Scala 2.10.1.
using Scala 2.10.1.
例如,我希望 Seq.newBuilder
返回一个 VectorBuilder
.如果结果显式输入到 Seq
,则由 CanBuildFrom
返回:
I would expect Seq.newBuilder
to return a VectorBuilder
for example. This is returned by CanBuildFrom
, if the result is explicitly typed to a Seq
:
def build[T, C <: Iterable[T]](x: T, y: T)
(implicit cbf: CanBuildFrom[Nothing, T, C]): C = {
val b = cbf()
println(b.getClass.getName)
b += x
b += y
b.result()
}
val s: Seq[Int] = build(1, 2)
println(s.getClass.getName) // scala.collection.immutable.Vector
在这种情况下,构建器是一个 VectorBuilder
,结果的类是一个 Vector
.
in this case the builder is a VectorBuilder
, and the result's class is a Vector
.
所以我明确地想要构建一个 Seq
,但结果是一个 List
,它需要更多的 RAM,根据 Scala 集合内存占用特征.
So I explicitly wanted to build a Seq
, but the result is a List
which needs more RAM, according to Scala collection memory footprint characteristics.
那么为什么 Seq.newBuilder
会返回一个 ListBuffer
并最终给出一个 List
?
So why does Seq.newBuilder
return a ListBuffer
which gives a List
in the end?
推荐答案
Scala Collections API 非常复杂,层次结构很深.每个级别代表某种新的抽象.Seq
trait 分为两个不同的子 trait,为性能提供不同的保证 (ref.):
The Scala Collections API is very complex and its hierarchy is rich in depth. Each level represents some sort of new abstraction. The Seq
trait split up into two different subtraits, which give different guarantees for performance (ref.):
IndexedSeq
提供元素的快速随机访问和快速长度操作.IndexedSeq
的代表之一是Vector
.
An
IndexedSeq
provides fast random-access of elements and a fast length operation. One representative of thisIndexedSeq
is theVector
.
A LinearSeq
仅通过头部提供对第一个元素的快速访问,但也具有快速尾部操作.LinearSeq
的代表之一是 List
.
A LinearSeq
provides fast access only to the first element via head, but also has a fast tail operation. One representative of this LinearSeq
is the List
.
由于 Seq
的当前默认实现是一个 List
,Seq.newBuilder
将返回一个 ListBuffer
.但是,如果您想使用 Vector
,您可以使用 Vector.newBuilder[T]
或 IndexedSeq.newBuilder[T]
:>
As the current default implementation of a Seq
is a List
, Seq.newBuilder
will return a ListBuffer
. However, if you want to use a Vector
you can either use Vector.newBuilder[T]
or IndexedSeq.newBuilder[T]
:
scala> scala.collection.immutable.IndexedSeq.newBuilder[Int]
res0: scala.collection.mutable.Builder[Int,scala.collection.immutable.IndexedSeq[Int]] = scala.collection.immutable.VectorBuilder@1fb10a9f
scala> scala.collection.immutable.Vector.newBuilder[Int]
res1: scala.collection.mutable.Builder[Int,scala.collection.immutable.Vector[Int]] = scala.collection.immutable.VectorBuilder@3efe9969
这篇关于为什么 Seq.newBuilder 返回一个 ListBuffer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!