Scala 数组

在 Scala 中,数组(Array)是一种可变的、固定长度的序列数据结构,用于存储同一类型的元素。Scala 的数组基于 Java 的数组实现,但提供了更丰富的操作接口,结合了命令式和函数式编程特性。以下是对 Scala 数组的中文讲解,内容简洁清晰,涵盖定义、操作、特性及注意事项,适合初学者理解。


1. 数组概述

  • 定义:数组是固定长度的有序元素集合,元素通过索引(从 0 开始)访问,支持读写操作。
  • 特点
  • 可变性:数组元素可以修改(与 Scala 的不可变集合如 List 不同)。
  • 固定长度:创建后长度不可更改。
  • 类型安全:所有元素必须是同一类型(如 Int, String)。
  • 基于 Java 的 Array 类,但 Scala 提供更高级的 API。
  • 用途:适合需要索引访问或修改元素的场景,如数据处理或算法实现。

2. 数组的定义与初始化

Scala 数组使用 Array 类定义,支持多种初始化方式。

1. 使用 new Array

  • 语法:
  val 数组名 = new Array[类型](长度)
  • 示例:
  val numbers = new Array[Int](3) // 创建长度为 3 的 Int 数组
  numbers(0) = 1 // 设置元素
  numbers(1) = 2
  numbers(2) = 3
  println(numbers.mkString(", ")) // 输出: 1, 2, 3

2. 使用 Array() 构造器

  • 直接指定初始值,长度由元素个数决定。
  • 语法:
  val 数组名 = Array(元素1, 元素2, ...)
  • 示例:
  val fruits = Array("apple", "banana", "orange")
  println(fruits(0)) // 输出: apple

3. 类型推断

  • Scala 支持类型推断,省略类型声明:
  val mixed = Array(1, "Scala", true) // 推断为 Array[Any]
  println(mixed.mkString(", ")) // 输出: 1, Scala, true

4. 多维数组

  • 使用 Array.ofDim 创建多维数组:
  val matrix = Array.ofDim[Int](2, 3) // 2x3 矩阵
  matrix(0)(0) = 1
  matrix(1)(2) = 5
  println(matrix(0)(0)) // 输出: 1

3. 数组操作

Scala 数组支持丰富的操作,包括索引访问、修改、遍历和函数式方法。

1. 访问与修改

  • 使用 (索引) 访问或修改元素:
  val arr = Array(10, 20, 30)
  println(arr(1)) // 输出: 20
  arr(1) = 25 // 修改
  println(arr(1)) // 输出: 25

2. 遍历数组

  • for 循环
  val arr = Array("a", "b", "c")
  for (x <- arr) println(x)
  // 输出:
  // a
  // b
  // c
  • 索引遍历
  for (i <- arr.indices) println(s"Index $i: ${arr(i)}")
  // 输出:
  // Index 0: a
  // Index 1: b
  // Index 2: c
  • foreach 方法
  arr.foreach(println) // 输出: a, b, c

3. 常用方法

  • 长度lengthsize 获取数组长度。
  val arr = Array(1, 2, 3)
  println(arr.length) // 输出: 3
  • 连接mkString 将数组元素拼接为字符串。
  println(arr.mkString(", ")) // 输出: 1, 2, 3
  • 添加元素:数组长度固定,无法直接添加,但可创建新数组:
  val arr = Array(1, 2)
  val newArr = arr :+ 3 // 追加
  println(newArr.mkString(", ")) // 输出: 1, 2, 3
  • 函数式操作
  • map:转换元素。
    scala val doubled = arr.map(_ * 2) println(doubled.mkString(", ")) // 输出: 2, 4, 6
  • filter:筛选元素。
    scala val evens = arr.filter(_ % 2 == 0) println(evens.mkString(", ")) // 输出: 2
  • sum, max, min:数值数组的聚合操作。
    scala println(arr.sum) // 输出: 6 println(arr.max) // 输出: 3

4. 数组排序

  • 使用 sorted(创建新数组)或 sortInPlace(原地排序,Scala 3)。
  val arr = Array(3, 1, 2)
  val sorted = arr.sorted
  println(sorted.mkString(", ")) // 输出: 1, 2, 3

4. 数组的特点

  • 可变性:数组元素可修改,但长度固定。
  val arr = Array(1, 2, 3)
  arr(0) = 10 // 修改
  // arr = Array(4, 5) // 错误:不能重新赋值整个数组(除非用 var)
  • 与集合的区别
  • 数组是可变的,适合命令式编程。
  • 不可变集合(如 List)更适合函数式编程。
  • 性能:数组基于 Java 数组,索引访问效率高(O(1)),适合高性能场景。

5. 注意事项

  • 固定长度:数组长度不可变,需用 ListVector 处理动态长度需求。
  • 类型安全:数组元素类型必须一致,否则推断为 Any
  val mixed = Array(1, "Scala") // Array[Any]
  • 越界检查:访问非法索引会抛出 ArrayIndexOutOfBoundsException
  val arr = Array(1, 2)
  // println(arr(2)) // 错误:索引越界
  • 函数式替代:Scala 鼓励使用不可变集合(如 List)和函数式方法(如 map, filter)。
  • Scala 2 vs Scala 3
  • Scala 3 引入 sortInPlace 等新方法,语法更简洁。
  • 类型推断和错误提示更友好。
  • 与 Java 数组:Scala 数组直接映射到 Java 数组,兼容 Java 库。

6. 实践示例

综合示例,展示数组的创建和操作:

object ArrayDemo {
  def main(args: Array[String]): Unit = {
    // 创建数组
    val numbers = Array(3, 1, 4, 2)
    println(s"Original: ${numbers.mkString(", ")}") // 输出: 3, 1, 4, 2

    // 修改元素
    numbers(0) = 10
    println(s"Modified: ${numbers.mkString(", ")}") // 输出: 10, 1, 4, 2

    // 遍历
    println("For loop:")
    for (x <- numbers) println(x)

    // 函数式操作
    val doubled = numbers.map(_ * 2)
    println(s"Doubled: ${doubled.mkString(", ")}") // 输出: 20, 2, 8, 4

    // 排序
    val sorted = numbers.sorted
    println(s"Sorted: ${sorted.mkString(", ")}") // 输出: 1, 2, 4, 10

    // 多维数组
    val matrix = Array.ofDim[Int](2, 2)
    matrix(0)(0) = 1
    matrix(1)(1) = 4
    println(s"Matrix: ${matrix.map(_.mkString(", ")).mkString("; ")}")
    // 输出: 1, 0; 0, 4
  }
}

7. 学习建议

  • 实践:在 Scala REPL(运行 scala 命令)中测试数组操作,尝试 map, filter 和多维数组。
  • 函数式思维:优先考虑不可变集合(如 List),仅在需要可变性时使用数组。
  • 性能优化:数组适合高性能索引访问,但注意越界错误。
  • 资源
  • 官方文档:https://www.scala-lang.org/
  • Scala Exercises (https://www.scala-exercises.org/)
  • 《Programming in Scala》by Martin Odersky

如果需要深入讲解某一方面(如多维数组或与 List 的对比)或更多示例,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注