为什么 Seq.newBuilder 返回一个 ListBuffer? [英] Why is Seq.newBuilder returning a ListBuffer?

查看:29
本文介绍了为什么 Seq.newBuilder 返回一个 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.):

  1. IndexedSeq 提供元素的快速随机访问和快速长度操作.IndexedSeq 的代表之一是 Vector.

  1. An IndexedSeq provides fast random-access of elements and a fast length operation. One representative of this IndexedSeq is the Vector.

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 的当前默认实现是一个 ListSeq.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆