在 Scala 2.7.5 中将元素附加到列表的非弃用方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2221914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Non deprecated way of appending an element to a List in Scala 2.7.5?
提问by Geo
How do you add an element to a Listin Scala 2.7.5, without creating a new Listand without using a deprecated solution.
如何List在 Scala 2.7.5中将元素添加到 a ,而不创建新的List和不推荐使用的解决方案。
回答by Fabian Steeg
You could use a ListBuffer, which provides constant time append:
您可以使用 a ListBuffer,它提供恒定时间附加:
val buffer = new scala.collection.mutable.ListBuffer[Int]
buffer += 1
buffer += 2
val list = buffer.toList
回答by oxbow_lakes
It's worth pointing out that Listhas a very specific meaning in scala, which is not equivalent to the java.util.Listinterface. Listis a sealed, abstract class representing a recursivedata-structure which has a headand a tail. (There do exist Java list-like structures in scala, some of which are mutable.)
值得指出的是,List在scala中有非常具体的含义,并不等同于java.util.List接口。List是一个密封的抽象类,表示具有head和tail的递归数据结构。(Scala 中确实存在类似 Java 列表的结构,其中一些是可变的。)
Scala's Lists are immutable; modifying a list in any way is not possible, although you can create a new list be prepending to an existing one (which gives a new object back). Even though they are immutable, the structure is no more expensivein terms of object creation than, say, appending to a java.util.LinkedList
Scala 的Lists 是不可变的;以任何方式修改列表都是不可能的,尽管您可以在现有列表之前创建一个新列表(这会返回一个新对象)。尽管它们是不可变的,但就对象创建而言,该结构并不比追加到一个对象更昂贵java.util.LinkedList
The +method has been deprecated for good reason because it is inefficient; instead use:
该+方法已被弃用,因为它效率低下;而是使用:
val newList = theList ::: List(toAppend)
I suppose a different way would be to prepend with 2 reversals:
我想另一种方法是在前面加上 2 个逆转:
val newList = (toAppend :: theList.reverse).reverse
I doubt this is any more efficient! In general, if I want appendbehaviour, I use prependand then reverse(at the point of needing to access the list):
我怀疑这是否更有效率!一般来说,如果我想要追加行为,我使用prepend然后reverse(在需要访问列表时):
val newList = toAppend :: theList
//much later! I need to send the list somewhere...
target ! newList.reverse
回答by Daniel C. Sobral
Non deprecated way of appending an element to a List in Scala 2.7.5?
在 Scala 2.7.5 中将元素附加到列表的非弃用方法?
That does not exist, and it will never exist.
那不存在,也永远不会存在。
How do you add an element to a List in Scala 2.7.5, without creating a new List and without using a deprecated solution.
如何在 Scala 2.7.5 中向 List 添加元素,而不创建新 List 并且不使用已弃用的解决方案。
Use :::
使用:::
val newList = element :: oldList
Or, if listis a var,
或者,如果list是var,
list ::= element
It does not create a new List(though, it creates a new ::, also known as cons), and it adds an element to it.
它不会创建新的List(不过,它会创建一个新的::,也称为cons),并且会向其添加一个元素。
If you want to append elements to a sequence without creating a new sequence, use a mutable data structure.
如果您想在不创建新序列的情况下将元素追加到序列中,请使用可变数据结构。
回答by Ben James
The +=method on a list is deprecated because it adds an element to the tail, which is expensive. The least expensive way of adding an element to a list is to add to the head using ::=.
+=不推荐使用列表上的方法,因为它向尾部添加了一个元素,这很昂贵。将元素添加到列表的最便宜的方法是使用::=.
So the deprecation warning is a subtle hint that you should redesign your program to work by prepending instead of appending:
因此,弃用警告是一个微妙的提示,您应该通过添加而不是附加来重新设计程序以使其工作:
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)
(Note that ::=and +=on a varare not real methods, but sugar for l = l :: elem, etc)
(请注意,::=和+=on avar不是真正的方法,而是用于l = l :: elem等的糖)
回答by Jens Schauder
This should do it: 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/SingleLinkedList.html#append%28This%29
Or this: http://www.scala-lang.org/docu/files/api/scala/collection/mutable/ListBuffer.html#%2B%3A%28A%29
或者这个:http: //www.scala-lang.org/docu/files/api/scala/collection/mutable/ListBuffer.html#%2B%3A%28A%29
The basic trick is to use a mutable List (or class with similiar functionality)
基本技巧是使用可变列表(或具有类似功能的类)
回答by James McMahon
The following is not true for certain operations List implementation. Thanks to sschaef for the correction.
以下不适用于某些操作 List 实现。感谢 sschaef 的更正。
A very important point that I haven't seen mentioned here is that creating a new collection from another collection necessarily isn't as expensive in Scala as it is in Java. This concept is called persistence. Daniel Spiewak lays it out in his article, http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-1.
我在这里没有看到的一个非常重要的点是,从另一个集合创建一个新集合在 Scala 中不一定像在 Java 中那样昂贵。这个概念称为持久性。Daniel Spiewak 在他的文章http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-1 中阐述了这一点。
Here is a snippet of the relevant section,
这是相关部分的片段,
Of course, the natural question which comes to mind is, what about performance? If each invocation actually creates a brand new Set for every recursive call, doesn't that require a lot of inefficient object copying and heap operations? Well, as it turns out, this isn't really the case. Yes, a new instance must be created at each turn, which is is a comparatively expensive operation on the JVM, but almost nothing is being copied. All of Scala's immutable data structures have a property known as persistence, which means that you don't copy the data out of the old container when creating a new, you just have the new reference the old and treat all of its contents as if they were its own.
当然,想到的自然问题是,性能怎么样?如果每次调用实际上为每次递归调用都创建了一个全新的 Set,那岂不是需要大量低效的对象复制和堆操作?好吧,事实证明,事实并非如此。是的,每次都必须创建一个新实例,这是 JVM 上相对昂贵的操作,但几乎没有复制任何内容。Scala 的所有不可变数据结构都有一个称为持久性的属性,这意味着您在创建新容器时不会从旧容器中复制数据,您只需将新引用作为旧容器,并将其所有内容视为它们是它自己的。
So while it will be less expensive to use a mutable list it isn't as much of a concern as it is under Java.
因此,虽然使用可变列表的成本会更低,但它不像在 Java 下那样令人担忧。

