如何在Scala 2.7.5中向List
添加元素,而无需创建新的List
且不使用已弃用的解决方案。
答案 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
或者,如果list
是var
,
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)
或者这个: http://www.scala-lang.org/docu/files/api/scala/collection/mutable/ListBuffer.html#%2B%3A%28A%29
基本技巧是使用可变列表(或具有类似功能的类)
答案 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那样令人担忧。