List 如何在Scala中复制列表
我想在Scala中复制一个列表 我想做一些事情,比如:List 如何在Scala中复制列表,list,scala,copy,shallow-copy,List,Scala,Copy,Shallow Copy,我想在Scala中复制一个列表 我想做一些事情,比如: val myList = List("foo", "bar") val myListCopy = myList.clone 但是克隆方法受保护。要筛选列表: 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) /
val myList = List("foo", "bar")
val myListCopy = myList.clone
但是克隆方法受保护。要筛选列表:
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)
您还可以使用通配符保存几个字符:
val evens = list.filter(_%2==0)
注意,如上所述,列表是不可变的。这意味着这些操作不会修改原始列表,而是实际创建一个新列表。这里没有答案:不要这样做。
列表
是不可变的,因此复制一个列表绝对没有意义
让我们考虑一些操作:
val list = List(1,2,3)
val l1 = 0 :: list
val l2 = "a" :: list
l1
和l2
都没有改变list
,但它们都创建了引用list
的新列表
让我们详细解释一下。构造函数List(1,2,3)
正在创建三个元素,并使用单例对象。具体地说,它正在实例化这些元素:
::(3, Nil)
::(2, reference to the previous element)
::(1, reference to the previous element)
而Nil
是一个单例对象。标识符列表
实际指向的是最后一个元素
现在,当您将0::list
分配给l1
时,您正在实例化一个新对象:
::(0, reference to ::(1, etc))
当然,由于有一个对列表的引用
,您可以将l1
视为一个包含四个元素的列表(如果将Nil
计算为五个元素)
现在l2
甚至不属于同一类型的列表
,但它也引用了它!在这里:
::("a", reference to ::(1, etc))
然而,所有这些对象的重要一点是它们不能被改变。没有任何setter,也没有任何方法会更改它们的任何属性。它们的“头”(我们称之为第一个元素)中永远有相同的值/引用,而“尾”(我们称之为第二个元素)中永远有相同的引用
但是,有些方法看起来像是在更改列表。不过,请放心,他们正在创建新的列表。例如:
val l3 = list map (n => n + 1)
方法映射创建一个大小相同的全新列表,其中新元素可以从列表
中的对应元素计算出来(但您也可以忽略旧元素)
虽然l4
的元素与list
相同(但类型不同),但它也是一个全新的列表。方法filter
根据您传递的规则创建一个新列表,告诉它哪些元素进入,哪些元素不进入。它不会尝试优化,以防返回现有列表
val l5 = list.tail
这不会创建新列表。相反,它只是将l5
分配给list
的现有元素
val l6 = list drop 2
同样,没有创建新列表
val l7 = list take 1
然而,这创建了一个新的列表,正是因为它不能更改list
的第一个元素,使其尾部指向Nil
以下是一些附加的实施细节:
是一个抽象类。它有两个子类,类List
(是的,这是类的名称),和单例对象:
<代码>列表是密封的,所以不能向其中添加新的子类,Nil
是最终的,所以不能对其进行子类化:
- 虽然您无法更改列表,但在某些操作中,它在内部使用可变状态。这有助于提高性能,但它是本地化的,因此您编写的任何程序都无法检测到它,也不会因此受到影响。无论其他函数如何处理列表,或者有多少线程同时使用列表,您都可以按自己的意愿传递列表
myList.remove(s=>s startsWith“f”)
时,会在删除foo
的位置创建一个新列表<代码>我的列表保持不变。正如亚历山大·阿扎罗夫(Alexander Azarov)已经说过的那样,列表在Scala中默认是不可变的。用户请求一种复制列表(根据示例,我想是字符串列表)的方法,您的答案是创建一个新列表,过滤整数列表中的奇数元素。为什么这个回答被认为是最好的答案?我遗漏了什么?当问题要求克隆时,您如何回答筛选相关列表?
val l7 = list take 1