List 是比较重要的一个集合类,抽象,sealed 。
首先位置
val List = scala.collection.immutable.List
scala 由 head 和 tail组成,head 只占一个对象(Int,String),
tail 又是由head 和 tail组成
由此循环变成List
所以里面drop方法,将these.taill 赋值到these 就删除了一个head。
override def drop(n: Int): List[A] = { var these = this var count = n while (!these.isEmpty && count > 0) { these = these.tail count -= 1 } these }
类定义为sealed abstact ,限制不能new ,无法被其他非同源继承(参考:scala 随笔(6)apply 解析和构造类),唯一的两个子类 Nil 和::
sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]] with scala.Serializable {
子类Nil ,定义了所有的nothing的情况,比如val list = Nil
case object Nil extends List[Nothing] {
override def isEmpty = true
override def head: Nothing =
throw new NoSuchElementException("head of empty list")
override def tail: List[Nothing] =
throw new UnsupportedOperationException("tail of empty list")
// Removal of equals method here might lead to an infinite recursion similar to IntMap.equals.
override def equals(that: Any) = that match {
case that1: scala.collection.GenSeq[_] => that1.isEmpty
case _ => false
}
}
里面的辅助类::
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] { override def tail : List[B] = tl override def isEmpty: Boolean = false }
唯一的入口:
override def apply[A](xs: A*): List[A] = xs.toList
会将输入的元素转换成List。
第一个函数 mkString,start,end 都是空字符,sep 就是输入的分隔符,就是将里面的元素依次串联起来。
def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = { var first = true b append start for (x <- self) { if (first) { b append x first = false } else { b append sep b append x } } b append end b }
第二个函数reduce
开始的时候不是太懂 reduce(_+_) 为啥可以做sum,
看里实现才发现里面定义了以一个acc 的临时值,然后第一个操作就是这个acc,第二个 才是list 里的成员,做的是op的方法。
def reduceLeft[B >: A](op: (B, A) => B): B = { if (isEmpty) throw new UnsupportedOperationException("empty.reduceLeft") var first = true var acc: B = 0.asInstanceOf[B] for (x <- self) { if (first) { acc = x first = false } else acc = op(acc, x) } acc }
第三方法map
map在里面重新new 里一个list 。
final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = { if (bf eq List.ReusableCBF) { if (this eq Nil) Nil.asInstanceOf[That] else { val h = new ::[B](f(head), Nil) var t: ::[B] = h var rest = tail while (rest ne Nil) { val nx = new ::(f(rest.head), Nil) t.tl = nx t = nx rest = rest.tail } h.asInstanceOf[That] } } else super.map(f) }
以上三个方法测试
object ListTest extends App{
val list = List(1,3,4,5);
print(list.mkString("+"))
val sum = list.reduce(_+_)
println("="+sum)
val list2 = list.map(x=>x)
if(list2 eq list){
println(" list2 == list")
}else{
println(" list2 != list")
}
list2.map(println(_))
}
输出结果为:
1+3+4+5=13
list2 != list
1
3
4
5
Process finished with exit code 0
看看其他几个方法: takeWhite 。这里也是定义ListBuffer,然后toList
@inline final override def takeWhile(p: A => Boolean): List[A] = {
val b = new ListBuffer[A]
var these = this
while (!these.isEmpty && p(these.head)) {
b += these.head
these = these.tail
}
b.toList
}
splitAt会分成两个List
override def splitAt(n: Int): (List[A], List[A]) = {
val b = new ListBuffer[A]
var i = 0
var these = this
while (!these.isEmpty && i < n) {
i += 1
b += these.head
these = these.tail
}
(b.toList, these)
}
slice 先删除lo 然后 take until-lo 个, 这个写法比较合scalar写法drop lo take (until - lo)
override def slice(from: Int, until: Int): List[A] = { val lo = scala.math.max(from, 0) if (until <= lo || isEmpty) Nil else this drop lo take (until - lo) }
drop 方法在上面已经说明。
List 到此结束