Scala 可变列表和ListBuffer之间的区别
Scala的Scala 可变列表和ListBuffer之间的区别,scala,scala-collections,Scala,Scala Collections,Scala的Scala.collection.mutable中的MutableList和ListBuffer类之间有什么区别?你什么时候会用一个和另一个 我的用例有一个线性序列,在这个序列中,我可以有效地删除第一个元素prepend和append。这方面的最佳结构是什么?这为您提供了性能特征的概述:;有趣的是,MutableList和ListBuffer在这两个方面没有区别。MutableList的文档说明它在内部用作堆栈和队列的基类,因此从用户角度来看,ListBuffer可能更像是一个正式的
Scala.collection.mutable
中的MutableList
和ListBuffer
类之间有什么区别?你什么时候会用一个和另一个
我的用例有一个线性序列,在这个序列中,我可以有效地删除第一个元素prepend和append。这方面的最佳结构是什么?这为您提供了性能特征的概述:;有趣的是,
MutableList
和ListBuffer
在这两个方面没有区别。MutableList
的文档说明它在内部用作堆栈和队列的基类,因此从用户角度来看,ListBuffer
可能更像是一个正式的类?您想要一个可扩展和可收缩的列表(为什么是列表?),并且需要常量追加和前置。嗯,Buffer
,一种特性,具有常量append和prepend,而大多数其他操作是线性的。我猜ListBuffer
,一个实现Buffer
的类,有固定时间删除第一个元素
因此,我个人的建议是对它们的工作原理做一点解释
ListBuffer
在内部使用Nil
和:
构建一个不可变的列表
,并允许固定时间删除第一个和最后一个元素。为此,它将指针保留在列表的第一个和最后一个元素上,并且实际上允许更改(否则是不可变的):
类的头和尾(由:
的私有[scala]var
成员允许的好把戏)。它的toList
方法也会在固定时间内返回正常的不可变List
,因为它可以直接返回内部维护的结构。它也是不可变的列表
s的默认构建器(因此可以合理地预期它具有恒定的时间附加)。如果调用toList
,然后再次将一个元素附加到缓冲区中,则需要与缓冲区中当前元素数成线性关系的时间来重新创建新结构,因为它不能再改变导出的列表
MutableList
在内部与LinkedList
一起工作,而是一个(公开的,不象:
)可变链表实现,它知道其元素和后续元素(象:
)MutableList
还保留指向第一个和最后一个元素的指针,但是toList
以线性时间返回,因为生成的List
是从LinkedList
构建的。因此,在导出列表后,无需重新初始化缓冲区
考虑到您的需求,我认为ListBuffer
和MutableList
是等效的。如果你想在某个时候导出他们的内部列表,那么问问你自己在哪里需要开销:当你导出列表时,如果你继续修改缓冲区(然后选择MutableList
),那么就没有开销,或者只有当你再次修改缓冲区,并且在导出时没有开销(然后选择ListBuffer
)
我的猜测是,在2.8集合大修中,MutableList
早于ListBuffer
和整个Builder
系统。实际上,MutableList
在集合中非常有用。mutable
包:它有一个private[mutable]def-toLinkedList
方法,该方法以恒定时间返回,因此可以有效地用作内部维护LinkedList
的所有结构的委托生成器
因此,我还建议您使用ListBuffer
,因为它将来可能会比MutableList
和LinkedList
等“纯可变”结构更受关注和优化。首先,让我们看一下Scala中的一些相关类型
列表
-不可变的集合。递归实现,即。i、 一个list实例有两个主要元素head和tail,其中tail引用另一个list
List[T]
head: T
tail: List[T] //recursive
LinkedList
-定义为一系列链接节点的可变集合,其中每个节点包含一个值和指向下一个节点的指针
Node[T]
value: T
next: Node[T] //sequential
LinkedList[T]
first: Node[T]
与在命令式语言中更为标准的LinkedList相比,List是一种功能性数据结构(不变性)
现在,让我们看看
ListBuffer
-一种由列表支持的可变缓冲区实现
MutableList
-一个基于LinkedList的实现(如果它被命名为LinkedListBuffer
,则更容易解释)
但是,如果您从可变列表
请求列表
,那么它必须将现有的线性表示转换为递归表示,该表示采用O(n),这是@Jean-Philippe Pellet指出的。但是,如果您从MutableList
请求Seq
,复杂性为O(1)
因此,在我看来,选择范围缩小到您的代码和偏好的细节。不过,我怀疑还有更多的List
和ListBuffer
。请注意,ListBuffer是最终的/密封的,而您可以扩展可变列表。
根据您的应用程序,可扩展性可能很有用。我认为ListBuffer不允许常数时间获取/删除最后一个元素!看来你是对的——似乎不是。太糟糕了,因为它很容易做到。