将元素添加到Scala中的不可变列表

时间:2015-02-14 08:22:17

标签: list scala insertion-order

在Scala中,您将元素添加到不可变列表的方式如下:

    val l = 1 :: 2 :: Nil
    l: List[Int] = List(1, 2)

这意味着您首先创建一个Nil(空)列表,然后添加2然后再添加1.即这些操作是右关联的。所以,实际上,它可以以更清晰的方式重写,如下所示:

    val l = (1 :: (2 :: Nil))
    l: List[Int] = List(1, 2)

问题是,如果List应该保留插入顺序,并且如果首先将2添加到空列表然后添加1,那么为什么答案不是l: List[Int] = List(2, 1) ??

2 个答案:

答案 0 :(得分:1)

这只是惯例。列表基本上是堆栈。访问或修改最近添加的项目效率最高。您也可以将列表的头部视为最终项目,在这种情况下,您建议的符号是合适的。

我推测这个约定的原因是我们通常不太关心列表的构建方式,但我们经常要考虑访问的第一个项目是订购中的初始项目,因此符号反映了这一点。

答案 1 :(得分:1)

这是因为元素是前置的:首先2然后是1

从cons方法的定义:

  def ::[B >: A] (x: B): List[B] =
    new scala.collection.immutable.::(x, this)

在这里,您可以看到每次创建案例类scala.collection.immutable.::的新实例时:

case class ::[B](val head: B, var tail: List[B]) extends List[B]

您只需将新元素用作head作为新列表,将整个上一个列表用作tail

对不可变List的前置操作也需要恒定时间O(1),追加为线性O(n)(来自Scala docs)。