在Scala 2.7.5中将元素附加到List的非弃用方法?

时间:2010-02-08 13:43:32

标签: list scala deprecated

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

6 个答案:

答案 0 :(得分:24)

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

val buffer = new scala.collection.mutable.ListBuffer[Int]
buffer += 1
buffer += 2
val list = buffer.toList

答案 1 :(得分:17)

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

Scala的List不可变的;虽然您可以创建一个新的列表,但是可以在现有的列表之前创建一个新的列表(它会返回一个新的对象),但是无法以任何方式修改列表。尽管它们是不可变的,但就对象创建而言,结构不再是昂贵的,而是附加到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

答案 2 :(得分:15)

  

非弃用的附加方式   元素到Scala 2.7.5中的List?

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

  

如何在List中添加元素   Scala 2.7.5,没有创建新的   列出并且不使用已弃用的   溶液

使用::

val newList = element :: oldList

或者,如果listvar

list ::= element

它不会创建新的List(但是,它会创建一个新的::,也称为 cons ),并且会向其添加一个元素。

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

答案 3 :(得分: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)

(请注意::=上的+=var不是真正的方法,而是l = l :: elem的糖等等)

答案 4 :(得分:1)

答案 5 :(得分: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那样令人担忧。