如何在 Scala 中复制列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1445629/
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
How to copy a list in Scala
提问by Maxime
I want to shallow copy a list in Scala.
我想在 Scala 中浅复制一个列表。
I wanted to do somehing like:
我想做类似的事情:
val myList = List("foo", "bar")
val myListCopy = myList.clone
But the clone method is protected.
但是克隆方法是受保护的。
采纳答案by Jon Hoffman
To filter a list:
要过滤列表:
val list = List(1,2,3,4,5)
//only evens
val evens = list.filter(e=>e%2 == 0)
println(list)
//--> List(1, 2, 3, 4, 5)
println(evens)
//--> List(2, 4)
You can also use the wildcard to save a few characters:
您还可以使用通配符来保存几个字符:
val evens = list.filter(_%2==0)
Note that, as commented above, lists are immutable. That means that these operations do not modify the original list, but actually create a new list.
请注意,如上所述,列表是不可变的。这意味着这些操作不会修改原始列表,而是实际创建一个新列表。
回答by Daniel C. Sobral
Here's a non-answer: don't do that. A Listis immutable, so there's absolutely no point in copying one.
这是一个非答案:不要那样做。 AList是不可变的,所以复制一个绝对没有意义。
Let's consider a few operations:
让我们考虑一些操作:
val list = List(1,2,3)
val l1 = 0 :: list
val l2 = "a" :: list
Neither l1nor l2are altering list, but they both create new lists that reference list.
既没有l1也没有l2改变list,但它们都创建了引用list.
Let's explain this in detail. The constructor List(1,2,3)is creating three elements, and using a singleton object as well. Specifically, it is instantiating these elements:
让我们详细解释一下。构造函数List(1,2,3)正在创建三个元素,并使用一个单例对象。具体来说,它正在实例化这些元素:
::(3, Nil)
::(2, reference to the previous element)
::(1, reference to the previous element)
And Nilis a singleton object. What the identifier listactually points to is that last element.
并且Nil是一个单例对象。标识符list实际指向的是最后一个元素。
Now, when you assign 0 :: listto l1, you are instantiating one new object:
现在,当您分配0 :: list给 时l1,您正在实例化一个新对象:
::(0, reference to ::(1, etc))
Of course, since there's a reference to list, you can think of l1as a list of four elements (or five, if you count Nil).
当然,由于有对 的引用list,您可以将其l1视为包含四个元素(或五个,如果算上Nil)的列表。
Now l2isn't even of the same type of list, but it ALSO references it! Here:
现在l2甚至不是同一类型的list,但它也引用了它!这里:
::("a", reference to ::(1, etc))
The important point about all these objects, though, is that they can't be changed. There are no setters, nor any methods that will change any of their properties. They'll be forever having the same values/reference in their "head" (that's what we call the first element), and the same references in their "tail" (that's what we call the second element).
但是,关于所有这些对象的重要一点是它们无法更改。没有设置器,也没有任何方法可以改变它们的任何属性。它们的“头部”(这就是我们所说的第一个元素)中将永远具有相同的值/引用,并且它们的“尾部”(这就是我们所说的第二个元素)中具有相同的引用。
However, there are methods that looklike their are changing the list. Rest assured, however, that they are creating newlists. For instance:
但是,有些方法看起来像是在更改列表。但是请放心,他们正在创建新列表。例如:
val l3 = list map (n => n + 1)
The method map creates a completely new list, of the same size, where new element may be computed from a corresponding element in list(but you might ignore the old element as well).
方法 map 创建了一个全新的、大小相同的列表,其中新元素可以从对应的元素中计算出来list(但你也可以忽略旧元素)。
val l4 = l2 filter (n => n.isInstanceOf[Int])
While l4has the same elements as list(but a different type), it is also a completely new list. The method filtercreates a new list, based on a rule you pass to tell it what elements go in and what don't. It doesn't try to optimize in case it couldreturn an existing list.
虽然l4与list(但类型不同)具有相同的元素,但它也是一个全新的列表。该方法filter根据您传递的规则创建一个新列表,告诉它哪些元素可以进入,哪些不能。它不会尝试优化,以防它可以返回现有列表。
val l5 = list.tail
This does not create a new list. Instead, it simply assigns to l5an existing element of list.
这不会创建新列表。相反,它只是分配给l5的现有元素list。
val l6 = list drop 2
Again, no new list created.
同样,没有创建新列表。
val l7 = list take 1
This, however, creates a new list, precisely because it can't change the first element of listso that its tail points to Nil.
然而,这会创建一个新列表,正是因为它无法更改 的第一个元素list,使其尾部指向Nil。
Here's a few additional implementation details:
下面是一些额外的实现细节:
Listis an abstract class. It has two descendants, the class::(yes, that's the name of the class), and the singleton objectNil.Listis sealed, so you can't add new subclasses to it, and::is final, so you can't subclass it.While you can't do anything to change a list, it uses mutable state internally in some operations. This helps with performance, but it is localized so that no program you write can ever detect it, or suffer consequences from it. You can pass lists around as you wish, no matter what the other functions do with them, or how many threads are using them concurrently.
List是一个抽象类。它有两个后代,即类::(是的,这就是类的名称)和单例对象Nil。List是密封的,所以你不能向它添加新的子类,并且::是最终的,所以你不能子类化它。虽然您无法更改列表,但它在某些操作中内部使用可变状态。这有助于提高性能,但它是本地化的,因此您编写的任何程序都无法检测到它,或遭受其后果。您可以随意传递列表,无论其他函数如何处理它们,或者有多少线程同时使用它们。

