9

如何List在 Scala 2.7.5 中向 a 添加元素,而不创建新元素List且不使用已弃用的解决方案。

4

6 回答 6

24

您可以使用 a ListBuffer,它提供恒定时间追加:

val buffer = new scala.collection.mutable.ListBuffer[Int]
buffer += 1
buffer += 2
val list = buffer.toList
于 2010-02-08T14:08:57.640 回答
17

值得指出的是,List在scala中有一个非常具体的含义,并不等同于java.util.List接口。List是一个密封的抽象类,表示具有headtail的递归数据结构。(scala 中确实存在类似 Java 列表的结构,其中一些是可变的。)

Scala 的Lists 是不可变的;不可能以任何方式修改列表,尽管您可以创建一个新列表添加到现有列表之前(这会返回一个新对象)。即使它们是不可变的,该结构在对象创建方面并不附加到一个java.util.LinkedList

+方法已被弃用,因为它效率低下;改为使用:

val newList = theList ::: List(toAppend)

我想另一种方法是在前面加上 2 个反转:

val newList = (toAppend :: theList.reverse).reverse

我怀疑这是否更有效!一般来说,如果我想要追加行为,我会使用prepend然后reverse(在需要访问列表时):

val newList = toAppend :: theList
//much later! I need to send the list somewhere...
target ! newList.reverse
于 2010-02-08T13:52:14.833 回答
15

将元素附加到 Scala 2.7.5 中的列表的非弃用方式?

那不存在,也永远不会存在。

如何在 Scala 2.7.5 中将元素添加到列表中,而不创建新列表且不使用已弃用的解决方案。

使用::

val newList = element :: oldList

或者,如果listvar

list ::= element

它不会创建一个新的List(尽管它会创建一个新的::,也称为cons),而是向其中添加一个元素。

如果您想在不创建新序列的情况下将元素附加到序列,请使用可变数据结构。

于 2010-02-08T17:38:07.290 回答
2

不推荐使用列表上的+=方法,因为它向尾部添加了一个元素,这很昂贵。将元素添加到列表中最便宜的方法是使用::=.

因此,弃用警告是一个微妙的提示,您应该重新设计程序以通过预先而不是附加来工作:

scala> var l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)

scala> l ::= 4

scala> l
res1: List[Int] = List(4, 1, 2, 3)

(注意::=and +=on avar不是真正的方法,而是糖 forl = l :: elem等)

于 2010-02-08T13:46:29.410 回答
1

这应该这样做: http ://www.scala-lang.org/docu/files/api/scala/collection/mutable/SingleLinkedList.html#append%28This%29

或者这个: http ://www.scala-lang.org/docu/files/api/scala/collection/mutable/ListBuffer.html#%2B%3A%28A%29

基本技巧是使用可变列表(或具有类似功能的类)

于 2010-02-08T14:04:19.120 回答
1

对于某些操作 List 实现,以下内容不正确。感谢 sschaef 的更正。


我在这里没有提到的一个非常重要的一点是,从另一个集合创建一个新集合在 Scala 中不一定像在 Java 中那样昂贵。这个概念称为持久性。Daniel Spiewak 在他的文章http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-1中阐述了这一点。

这是相关部分的片段,

当然,自然会想到的问题是,性能呢?如果每个调用实际上为每个递归调用创建一个全新的 Set,那不是需要大量低效的对象复制和堆操作吗?好吧,事实证明,情况并非如此。是的,每次都必须创建一个新实例,这在 JVM 上是一项相对昂贵的操作,但几乎没有任何内容被复制。Scala 的所有不可变数据结构都有一个称为持久性的属性,这意味着您在创建新容器时不会将数据从旧容器中复制出来,您只需将新容器引用旧容器并将其所有内容视为是它自己的。

因此,虽然使用可变列表会更便宜,但它并不像在 Java 下那样令人担忧。

于 2012-07-15T19:08:53.117 回答