Scala中的list(一)

50 阅读2分钟

一、List 的基本特性

1. 不可变性 (Immutable)

val list1 = List(1, 2, 3)
val list2 = list1 :+ 4  // 创建新列表,list1 不变
// list1 仍然是 List(1, 2, 3)

2. 链表结构

  • 头部(head):第一个元素
  • 尾部(tail):剩余元素组成的列表
  • 空列表:Nil
val list = List(1, 2, 3)
val head = list.head    // 1
val tail = list.tail    // List(2, 3)

二、创建 List

1. 基本创建方式

// 使用伴生对象的 apply 方法
val list1 = List(1, 2, 3)

// 使用 Nil 和 ::(cons 操作符)
val list2 = 1 :: 2 :: 3 :: Nil

// 空列表
val empty1 = List()
val empty2 = Nil

// 范围创建
val rangeList = List.range(1, 5)  // List(1, 2, 3, 4)

2. 其他创建方法

// 填充相同元素
val sameElements = List.fill(3)("hello")  // List("hello", "hello", "hello")

// 生成序列
val tabulated = List.tabulate(5)(n => n * n)  // List(0, 1, 4, 9, 16)

// 连接多个列表
val concat = List.concat(List(1,2), List(3,4))  // List(1, 2, 3, 4)

三、基本操作

1. 访问元素

val list = List("a", "b", "c", "d")

list(0)      // "a" - 通过索引访问
list.head    // "a" - 第一个元素
list.tail    // List("b", "c", "d") - 除第一个外的所有元素
list.last    // "d" - 最后一个元素
list.init    // List("a", "b", "c") - 除最后一个外的所有元素

2. 添加元素(创建新列表)

val list = List(1, 2, 3)

// 在开头添加(高效)
val newList1 = 0 :: list      // List(0, 1, 2, 3)
val newList2 = 0 +: list      // 同上

// 在末尾添加(低效 - 需要遍历整个列表)
val newList3 = list :+ 4      // List(1, 2, 3, 4)

3. 连接列表

val list1 = List(1, 2)
val list2 = List(3, 4)

val combined1 = list1 ::: list2    // List(1, 2, 3, 4)
val combined2 = list1 ++ list2     // 同上

四、常用方法

1. 长度和检查

val list = List(1, 2, 3)

list.length     // 3
list.isEmpty    // false
list.nonEmpty   // true
list.size       // 3(同 length)

2. 反转和排序

val list = List(3, 1, 4, 2)

list.reverse          // List(2, 4, 1, 3)
list.sorted           // List(1, 2, 3, 4)
list.sortWith(_ > _)  // List(4, 3, 2, 1)

3. 查找元素

val list = List(1, 2, 3, 4, 5)

list.contains(3)      // true
list.indexOf(3)       // 2
list.find(_ > 3)      // Some(4)
list.exists(_ % 2 == 0)  // true(存在偶数)
list.forall(_ > 0)    // true(所有元素都大于0)

五、模式匹配

List 在模式匹配中非常强大:

def processList(list: List[Int]): String = list match {
  case Nil => "空列表"
  case head :: Nil => s"只有一个元素: $head"
  case first :: second :: tail => s"第一个: $first, 第二个: $second, 其余: $tail"
  case _ => "其他情况"
}

processList(List(1))        // "只有一个元素: 1"
processList(List(1, 2, 3))  // "第一个: 1, 第二个: 2, 其余: List(3)"

六、递归处理

由于 List 是链表,递归是处理它的自然方式:

// 计算列表长度
def length[A](list: List[A]): Int = list match {
  case Nil => 0
  case _ :: tail => 1 + length(tail)
}

// 求和
def sum(list: List[Int]): Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
}

七、性能特点

  • 头部访问和添加:O(1)
  • 随机访问:O(n)(需要遍历)
  • 尾部添加:O(n)(需要复制整个列表)
  • 适合:频繁的头部操作、递归处理
  • 不适合:需要频繁随机访问或尾部添加的场景

八、与 Java 互操作

import scala.jdk.CollectionConverters._

// Scala List 转 Java List
val scalaList = List(1, 2, 3)
val javaList: java.util.List[Int] = scalaList.asJava

// Java List 转 Scala List
val javaList2 = new java.util.ArrayList[Int]()
javaList2.add(1)
val scalaList2: List[Int] = javaList2.asScala.toList