scala 随笔(8)list 源码解析

本文深入剖析Scala中的List集合类,探讨其内部实现原理,包括head和tail的构成方式、辅助类的作用,以及drop、takeWhile等关键方法的工作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 
  1. case object Nil extends List[Nothing] {
  2. override def isEmpty = true
  3. override def head: Nothing =
  4. throw new NoSuchElementException("head of empty list")
  5. override def tail: List[Nothing] =
  6. throw new UnsupportedOperationException("tail of empty list")
  7. // Removal of equals method here might lead to an infinite recursion similar to IntMap.equals.
  8. override def equals(that: Any) = that match {
  9. case that1: scala.collection.GenSeq[_] => that1.isEmpty
  10. case _ => false
  11. }
  12. }

里面的辅助类::
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)
}

以上三个方法测试
  1. object ListTest extends App{
  2. val list = List(1,3,4,5);
  3. print(list.mkString("+"))
  4. val sum = list.reduce(_+_)
  5. println("="+sum)
  6. val list2 = list.map(x=>x)
  7. if(list2 eq list){
  8. println(" list2 == list")
  9. }else{
  10. println(" list2 != list")
  11. }
  12. list2.map(println(_))
  13. }
输出结果为:
1+3+4+5=13
 list2 != list
1
3
4
5

Process finished with exit code 0


看看其他几个方法: takeWhite 。这里也是定义ListBuffer,然后toList
  1. @inline final override def takeWhile(p: A => Boolean): List[A] = {
  2. val b = new ListBuffer[A]
  3. var these = this
  4. while (!these.isEmpty && p(these.head)) {
  5. b += these.head
  6. these = these.tail
  7. }
  8. b.toList
  9. }
splitAt会分成两个List
  1. override def splitAt(n: Int): (List[A], List[A]) = {
  2. val b = new ListBuffer[A]
  3. var i = 0
  4. var these = this
  5. while (!these.isEmpty && i < n) {
  6. i += 1
  7. b += these.head
  8. these = these.tail
  9. }
  10. (b.toList, these)
  11. }

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 到此结束








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值