List类的原理
-
-
List算是Scala中最常用的结构。是一个抽象类,有子类::和Nil组成,List的类型参数是协变的,列表的所有操作都可以通过以下三种操作进行定义:
def isEmpty: Boolean def head: T def tail: List[T]Nil对象定义了一个空列表,Nil对象继承自List[Nothing],也就是说Nil和任何列表都是兼容的,是任何列表的子类元素。Nil的head和tail对象都会抛出异常,因为没有值是Nothing类型的。::类,cons类表示非空列表,为了支持中缀::实现模式匹配。在模式匹配中,每个中缀操作数都被当做是入参来调用中缀操作符对应的构造方法。x :: xs = ::(x,xs),::中的head和tail直接返回构造参数中的对应部分。 -
-
- 代码
实现了三个函数,原因如下,在final case class ::[T](head: T, tail: List[T]) extends List[T] { override def isEmpty: Boolean = false }Scala的样例类中,每一个类参数都是类字段,Scala允许使用字段来实现抽象的无参方法。因此直接实现了head和tail参数。 -
List的其他方法基本都可以基于这三个方法实现。
-
-
:::的实现不是很懂?
-
ListBuffer
-
ListBuffer允许对列表的元素在尾部做累加进行修改,可以使用buf += elem的操作在buf尾部添加elem元素,一旦添加完成,可以使用toList操作将缓冲转换为列表。列表缓冲在追加操作+=和toList操作上都只消耗很短的常量时间。
-
-
List类的大多数方法的真实实现并没有使用递归,而是通过循环和列表缓冲。toList的操作只会有少量计算周期的开销,和列表的长度无关。
-
-
List的实现中涉及到了可变元素,List在外面看是纯函数式的,但实际实现用到了可变的列表缓冲,这是Scala编程的一个策略,高效而且方便使用。
-