如何将Vector设置为默认实现?

时间:2016-05-11 14:49:08

标签: list scala vector

在我阅读When should I choose Vector in Scala?时,无论是使用List还是Vector,问题都在Scala中得到与在Java中相同的答案:是否使用LinkedList的问题或ArrayList。您可能知道,答案是“在大多数情况下使用Vector / ArrayList”。

但是,根据http://docs.scala-lang.org/tutorials/FAQ/collections,在Scala中,ListTraversable的最终默认实现。我想这不是Vector,因为“它来晚了”。

  1. 或者还有另一个原因Vector不是更显优势吗?
  2. IndexedSeq设置为Seq的默认实现,因此Vector成为Traversable的最终默认实现是不是有意义?
  3. 我该怎么做?

2 个答案:

答案 0 :(得分:2)

scala.mutable.Vector基于trie structure,因此它在技术上比java.util.ArrayList复杂得多。这种复杂性意味着一堆List共享commong后缀可能比共享公共前缀的Vector串更轻量级。

该属性在功能样式中意味着很多,在这种情况下,您经常会有很多操作需要收集并返回其修改后的副本,例如stack。附加到大型Vector可以生成几个新对象,预先设置为List - 始终为一个。

List非常易于理解和推理。它只是::Nil

Vector的实施几乎是隐藏的,它有"dirty" optimisations,可以通过seq extractors优先匹配,这是指隐藏的优化drops

随机haskell开发人员可能希望Stream成为默认Seq而不是List。一些scalaz爱好者 - 希望more some symmetric Sequence导出到std lib。

由于scala.Seq.apply chosen newBuilder implementation的结果,您无法根据List更改ListBuffer选项。但是,您可以编写自己的类似Seq工厂,如

object Seq extends SeqFactory[Seq] {
  implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
  def newBuilder[A]: Builder[A, Seq[A]] = new VectorBuilder[A]
}

总结:

  1. 链接列表是历史上功能语言中最主要的集合类型
  2. 另一种序列类型在另一个域中可能更有用
  3. 你不能"切换" scala.Seq.apply到另一种通用类型。但是可以导入或创建名为Seq的其他对象。
  4. 我个人认为Vector(...)形式比IndexedSeq(...)更有用,更简洁。 List(...)代替Seq(...)LinearSeq(...)

答案 1 :(得分:1)

"在大多数情况下使用Vector"回答你习惯于在java中,不在scala中,因为它是一种不同的语言,具有不同的模式,工具和最佳实践。

大多数结构和变量是不可变的,并且算法在顺序处理数据流方面大部分时间表达。考虑到这两个观察结果,必须得出结论,最适合大多数用例的集合实现实际上是链表,而不是随机访问集。

因此,对问题#3的简短回答是"不要做"。稍微长一点的版本是:明确。如果您认为您想在某个地方使用IndexedSeq,请这样说:val seq = IndexedSeq(1,2,3)