MutableList和ListBuffer之间的区别

时间:2011-03-27 02:04:17

标签: scala scala-collections

MutableList中Scala的ListBufferscala.collection.mutable类有什么区别?你什么时候使用一个与另一个?

我的用例是一个线性序列,我可以有效地删除第一个元素,prepend和append。什么是最好的结构?

5 个答案:

答案 0 :(得分:34)

关于它们如何运作的一点解释。

ListBuffer使用内部Nil::来构建不可变List,并允许永久删除第一个和最后元素。为此,它将指针放在列表的第一个和最后一个元素上,并且实际上允许更改(否则是不可变的)::类的头部和尾部({{1}允许的好技巧)成员private[scala] var)。它的::方法在常量时间内返回正常的不可变toList,因为它可以直接返回内部维护的结构。它也是不可变List的默认构建器(因此确实可以合理地期望具有恒定时间附加)。如果调用List然后再将一个元素附加到缓冲区,则相对于缓冲区中当前元素数的线性时间将重新创建一个新结构,因为它不能再改变导出的列表。

toList在内部与MutableList合作,一个(公开的,不像LinkedList)可变链接列表实现,它知道它的元素和后继(如::)。 ::还会保留指向第一个和最后一个元素的指针,但MutableList会以线性时间返回,因为生成的toList是从List构建的。因此,在导出LinkedList后,不需要重新初始化缓冲区。

根据您的要求,我会说ListListBuffer是等价的。如果你想在某个时候导出他们的内部列表,那么问问自己你想要的开销:当你导出列表时,如果你继续改变缓冲区(然后去MutableList),或者只有如果你再次改变缓冲区,并且在导出时没有(然后转到MutableList)。

我的猜测是,在2.8集合大修中,ListBuffer早于MutableList和整个ListBuffer系统。实际上,BuilderMutableList包中主要有用:它具有collection.mutable方法,该方法以恒定时间返回,因此可以有效地用作维护所有结构的委托构建器内部private[mutable] def toLinkedList

所以我也建议使用LinkedList,因为它可能会在未来获得关注和优化,而不是ListBufferMutableList等“纯粹可变”的结构。

答案 1 :(得分:7)

这为您提供了性能特征的概述:http://www.scala-lang.org/docu/files/collections-api/collections.html;有趣的是,MutableListListBuffer并没有区别。 MutableList的文档说它在内部用作StackQueue的基类,所以从用户的角度来看,ListBuffer可能更像是官方类吗?

答案 2 :(得分:5)

您想要一个可扩展可收缩的列表(为什么是列表?),并且您需要不断的追加和前置。好吧,Buffer,一个特征,具有不断的追加和前置,其他大多数操作是线性的。我猜测ListBuffer,一个实现Buffer的类,可以不间断地删除第一个元素。

所以,我自己的建议是ListBuffer

答案 3 :(得分:2)

首先,让我们来看看Scala中的一些相关类型

List - 一个不可变的集合。递归实现,即。即列表实例有两个主要元素:头部和尾部,尾部引用另一个List

List[T]
  head: T
  tail: List[T]  //recursive

LinkedList - 一个可变集合,定义为一系列链接节点,其中每个节点都包含一个值和指向下一个节点的指针。

Node[T]
  value: T
  next: Node[T]  //sequential

LinkedList[T]
  first: Node[T]

List是一个功能数据结构(immutability),与LinkedList相比,在命令式语言中更为标准。

现在,让我们来看看

ListBuffer - 由 List 支持的可变缓冲区实施。

MutableList - 基于LinkedList的实现(如果已将其命名为 LinkedListBuffer ,则会更加自我解释)

They both offer similar complexity bounds on most operations.

但是,如果您从List请求MutableList,则必须将现有的线性表示转换为递归表示,该表示采用O(n),这是@ Jean-Philippe Pellet指出的出。但是,如果您从Seq请求MutableList,则复杂度为O(1)。

因此,IMO的选择范围缩小到您的代码和您的偏好的细节。但是,我怀疑还有更多ListListBuffer

答案 4 :(得分:0)

请注意,ListBuffer是final / sealed,而您可以扩展MutableList。 根据您的应用程序,可扩展性可能很有用。