繁体   English   中英

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

[英]Non deprecated way of appending an element to a List in Scala 2.7.5?

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

您可以使用ListBuffer ,它提供常量时间追加:

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

值得指出的是, List在scala中有一个非常具体的含义,它不等同于java.util.List接口。 List是一个密封的抽象类,表示具有头部尾部递归数据结构。 (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

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

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

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

使用::

val newList = element :: oldList

或者,如果listvar

list ::= element

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

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

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

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

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糖等)

对于某些操作List实现,以下情况并非如此。 感谢sschaef的纠正。


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

以下是相关部分的片段,

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM