在Scala中向列表中添加元素

35

我正在运行Scala 2.10.2。我想创建一个列表,然后向列表添加一些元素,并期望在调用列表名称时看到所有元素。但我观察到了一些相当奇怪的东西(至少对于我这个新手来说很奇怪)。以下是我在sbt控制台中尝试做的事情:

scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)

scala> l
res0: List[Double] = List(1.0, 5.5)

scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)

scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)

scala> l
res3: List[Double] = List(1.0, 5.5)

scala> 

首先,我创建了一个包含两个元素(1.0和5.5)的列表l。我调用l并得到了我期望的两个元素。现在我尝试使用:::向列表中添加另一个元素,它返回一个新列表,其中包含我添加的新元素(2.2和3.7)。太好了!我甚至查看了其他人的代码寻求帮助:Appending an element to the end of a list in Scala,以使用新的构造函数:+。所以在这个阶段,我很开心,但是当我调用l时,我得到了意外的结果:'res3: List[Double] = List(1.0, 5.5)。

那么我添加的元素在哪里?如何正确地添加这些元素,以便当我调用l时,我可以得到一个包含所有我添加的东西的新列表?


你的任何语句都没有修改l - Hunter McMillen
列表通常是不可变的。在后一种情况下,您创建了一个新列表,而原始列表保持不变。您可以使用可变列表或使用递归追加方法。在REPL中,您当然也可以执行以下操作:val transformed = List(l):+ 2.2,然后打印出新值。 - Stefan Kunze
4个回答

46

您正在使用不可变列表。对列表的操作将返回一个新列表,而原始列表保持不变。如果另一个类/方法持有对原始集合的引用并且依赖它保持不变,则此功能非常有用。您可以像以下这样使用不同命名的vals:

val myList1 = 1.0 :: 5.5 :: Nil 
val myList2 = 2.2 :: 3.7 :: mylist1

或者像这样使用变量

var myList = 1.0 :: 5.5 :: Nil 
myList :::= List(2.2, 3.7)

这是与以下语法等效的写法:

myList = myList.:::(List(2.2, 3.7))

或者您可以使用可变集合之一,例如

val myList = scala.collection.mutable.MutableList(1.0, 5.5)
myList.++=(List(2.2, 3.7))

不要与以下内容混淆,它不会修改原始的可变列表,而是返回一个新值:

myList.++:(List(2.2, 3.7))

然而,只有在对性能要求比较高的代码中才应该使用可变集合。不可变集合更容易理解和使用。一个很大的优点是,不可变的List和scala.collection.immutable.Vector是协变的。如果你还不了解这个概念,不用担心。其好处是你可以在不完全理解它的情况下使用它。因此,你默认使用的集合实际上是scala.collection.immutable.List,只是自动导入了它。

我倾向于将List作为我的默认集合。从2.12.6开始,Seq默认为不可变的Seq,在此之前,默认值是不可变的。


12

如果确实需要更改,请使用 import scala.collection.mutable.MutableList 或类似的方式。

import scala.collection.mutable.MutableList
val x = MutableList(1, 2, 3, 4, 5)
x += 6 // MutableList(1, 2, 3, 4, 5, 6)
x ++= MutableList(7, 8, 9) // MutableList(1, 2, 3, 4, 5, 6, 7, 8, 9)

8

我会尝试解释您尝试的所有命令的结果。

scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)

首先,List 是对 scala.collection.immutable.List(在 Predef.scala 中定义)的类型别名。

使用 List 伴生对象是实例化 List 更为简单的方式。例如:List(1.0,5.5)

scala> l
res0: List[Double] = List(1.0, 5.5)

scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)

::: 返回一个列表,该列表是给定前缀列表和当前列表连接而成的结果。

原始列表不会被修改。

scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)

List(l) 是一个 List[List[Double]],绝对不是你想要的。

:+ 返回一个新列表,其中包含此列表中的所有元素,后跟 elem。

类型是 List[Any],因为它是 List[Double]Double 之间的公共超类。

scala> l
res3: List[Double] = List(1.0, 5.5)

因为在immutable.List上没有修改List的方法,所以l保持不变。


2

如果您想将元素添加到现有列表中,可以使用var List [Int],然后不断向同一列表添加元素。

注意 -> 您必须确保按以下方式将元素插入现有列表:

var l:List [int] = List()//创建空列表

l = 3 :: l //将3添加到列表头部

l = 4 :: l //将int 4作为列表的头部

//现在当您打印l时,您将在列表中看到两个元素(4,3)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接