2012-06-15 21 views
28

(把它作为后续的这个问题 - No Scala mutable list要使用哪个scala可变列表?

我想在scala中使用一个可变列表。我可以从

这是很好的,但什么是 “标准”,推荐,地道的斯卡拉方式选择?我只想使用一个列表,我可以在背面添加东西。

编辑:

好的,进一步扩大。

我正在使用一个HashMap,其中“列表”(我的意思是它的一般意义)将在价值方面。然后,我正在从文件中读取一些内容,并且对于每一行,我想在散列映射中找到正确的列表并将该值附加到列表中。

+2

你应该扩展你将如何使用它 - 因为从一般意义上讲,惯用的Scala方式根本不是使用可变列表(而是使用折叠或递归与不可变列表)。 –

+0

我认为你的列表可以是不可变的。你可以简单地加入一个不可变列表,并将你的HashMap条目更新为新创建的列表。 – ziggystar

+0

那么,在这种情况下,我将不得不改变散列表而不是列表。现在,我不更改散列表,但我更改列表。 –

回答

14

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

+0

太好了!我想接受这个答案,3年后, –

+0

接受。对不起@ axel22,但他在2012年尽了全力 –

33

取决于你需要什么。

DoubleLinkedList是一个链接列表,它允许您遍历节点列表来回遍历。使用它的prevnext引用分别转到上一个或下一个节点。

LinkedList是一个单向链表,所以没有prev指针 - 如果你只是遍历列表中的下一个元素,这就是你所需要的。

编辑:请注意,上述两个是意在用于内部作为像MutableList S的支持高效追加,和mutable.Queue S比复杂的列表结构的构建块。

以上两个集合都有线性时间附加操作。

ListBuffer是一个缓冲区类。尽管它由单链表数据结构支持,但它不会将next指针暴露给客户端,因此您只能使用迭代器和foreach来遍历它。 但是,它的主要用途是作为缓冲区和不可变列表生成器 - 您通过+=将元素附加到它,并且当您拨打result时,您将非常有效地取回功​​能immutable.List。与可变列表和不可变列表不同,append和prepend操作都是恒定时间 - 您可以非常高效地通过+=在末尾添加。

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

+0

链表真的有线性附加?为什么?单向和双向链表都可以支持不断追加,至少在完全可变的世界中。 – svick

+0

是的,他们做 - 见这里:https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/mutable/LinkedListLike.scala#L1。为什么?设计决定是让每个节点本身成为一个链表 - 否则你需要在开始和结束节点引用周围进行包装,这正是“MutableList”的意思。 – axel22

+0

我在文档中没有看到“哪个列表最适合删除元素”的答案,例如如果我打算建立一个清单,然后一次删除多个物品? – Hamy

9

如果你想附加项目,你根本不应该使用ListList当你想要预先安排项目时,这很好。改为使用ArrayBuffer

+5

我不同意。如果你不需要随机访问,'ListBuffer'比'ArrayBuffer'具有更好的性能特征,它需要随时调整大小。当然,追加操作可能会以* amortized *常量或其他方式运行,这并不坏,但我在这里看不到'ArrayBuffer'的任何优点。 – rolve

+5

@rolve分配的常量时间通常会更快,因为在JVM上分配新对象所涉及的常量(以及处理相关的GC压力)非常高,而调整大小操作发生得非常少(平均每个项目被复制两次)。更不用说ArrayBuffer的缓存局部性好处了,这对现代CPU来说可能是巨大的。 –

+2

@JohnColanduoni自从我发表评论以来,差不多3年过去了,我同意'ArrayBuffer'可能是更好的选择。无论如何,实际的绩效测量应该被用作此次讨论的基础。 :) – rolve

2

我只是想使用一个列表,我可以在背面添加东西。

然后选择一些实现Growable。我个人建议其中一个Buffer实现。

我远离LinkedListDoubleLinkedList,因为它们主要作为其他集合的底层实现存在,但是在Scala 2.9.x中有很多错误。从Scala 2.10.0开始,我希望各种错误修复都能使它们达到标准。尽管如此,他们仍然缺乏一些人们期望的方法,例如+=,你可以在这些方法的基础上找到它们。