要使用哪个scala可变列表?

要使用哪个scala可变列表?,scala,scala-collections,Scala,Scala Collections,这是我们的后续问题 我想在Scala中使用可变列表。我可以从中选择 这很好,但是什么是“标准”,推荐的,惯用的scala方式?我只想使用一个列表,我可以在后面添加内容 在我的例子中,我使用的是一个HashMap,其中“列表”(我的意思是一般意义上的列表)将位于值端。然后,我从文件中读取一些内容,对于每一行,我都希望在hashmap中找到正确的列表,并将值附加到列表中。取决于您需要什么 DoubleLinkedList是一个链接列表,允许您在节点列表中来回遍历。使用其prev和next

这是我们的后续问题

我想在Scala中使用可变列表。我可以从中选择

这很好,但是什么是“标准”,推荐的,惯用的scala方式?我只想使用一个列表,我可以在后面添加内容

在我的例子中,我使用的是一个HashMap,其中“列表”(我的意思是一般意义上的列表)将位于值端。然后,我从文件中读取一些内容,对于每一行,我都希望在hashmap中找到正确的列表,并将值附加到列表中。

取决于您需要什么

DoubleLinkedList
是一个链接列表,允许您在节点列表中来回遍历。使用其
prev
next
引用分别转到上一个或下一个节点

LinkedList
是一个单链接列表,因此没有
prev
指针-如果您一直只遍历列表的下一个元素,这就是您所需要的

编辑:请注意,上面两个用于内部作为更复杂列表结构的构建块,如支持高效追加的
MutableList
s和
mutable.Queue
s

上面的两个集合都具有线性时间附加操作

ListBuffer
是一个缓冲类。尽管它由一个单链表数据结构支持,但它不公开指向客户端的
next
指针,因此只能使用迭代器和
foreach
遍历它。 但是,它的主要用途是作为缓冲区和不可变列表生成器—通过
+=
向其添加元素,当调用
result
时,您可以非常高效地返回一个功能性的
不可变的.list
。与可变和不可变列表不同,append和prepend操作都是固定时间的-您可以通过
+=
非常有效地在末尾追加


MutableList
在内部使用,除非您计划基于单链表数据结构实现自定义集合类,否则通常不使用它。例如,可变队列继承此类
MutableList
类还有一个高效的常量时间附加操作,因为它维护了对列表中最后一个节点的引用。

如果要附加项,则根本不应该使用
列表<代码>列表
s在您想要预先添加项目时很好。改用
ArrayBuffer

我只想使用一个列表,我可以在后面添加内容

然后选择实现的东西。我个人建议使用一种
缓冲区
实现


我远离
LinkedList
DoubleLinkedList
,因为它们主要是作为其他集合的底层实现出现的,但在Scala 2.9.x之前有很多bug。从Scala2.10.0开始,我希望各种错误修复已经使它们达到了标准。尽管如此,它们仍然缺少人们所期望的一些方法,例如
+=
,您可以在基于它们的集合中找到这些方法。

为了让读者了解这个老问题:文档部分概述了可变列表类,包括关于何时使用哪一个的解释。

您可能应该详细介绍如何使用它,因为从一般意义上讲,Scala惯用的方法根本不是使用可变列表(而是使用折叠或递归处理不可变列表)。我认为您的列表可以是不可变的。你可以简单地在一个不可变列表的前面加上前缀,然后将你的HashMap条目更新到新创建的列表中。现在,我没有更改hashmap,但是我更改了列表。另请参阅,以了解ListBuffer和MutableList之间差异的解释。链接列表真的有线性附加吗?为什么?单链表和双链表都可以支持在固定时间内追加,至少在完全可变的世界中是这样。是的,它们可以-请参见此处:。为什么?设计决策是使每个节点本身成为一个链表——否则,您将需要一个围绕起始和结束节点引用的包装器,这正是
MutableList
的含义。我在文档中没有看到“哪个列表最擅长删除元素”的答案例如,如果我计划建立一个列表,然后一次删除一个项目?我找到这个页面是因为我也想知道标准的、推荐的、惯用的方法。从这个详细的解释中,我的印象是答案是
ListBuffer
。象牙塔是一个相当有力的陈述。标准库中名为
LinkedList
的类确实有一个用例,那就是构建更高的抽象。Scala中的
LinkedList
基本上是一个链表节点,因此是双链接
Queue
s、
MutableList
s和循环列表(即环)等类的构造块。在每个列表节点中存储长度、最后一个节点和类似项是毫无意义的。注意:
LinkedList
并不打算直接在典型的客户端代码中使用--
MutableList
Queue
immutable.ListBuffer
s和
immutable.List
s就属于这一类。我不同意。如果不需要随机访问,
ListBuffer
比需要不时调整大小的
ArrayBuffer
具有更好的性能特性。当然,append操作可能在摊销常量时间或其他时间运行,这并不坏,但我看不出
ArrayBuffer
在这里有任何优势。@rolve摊销常量时间最终通常更快,因为在JVM上分配新对象(以及处理相关GC压力)所涉及的常量非常高,虽然调整大小操作很少发生(平均每个项目复制两次)。更不用说ArrayBuffer的缓存局部性优势了,它可以是海量的