一、Scala 中 Array 的定义
Scala 的Array(数组)是固定长度、可索引的同类型元素容器,底层直接映射为 Java 的数组(如Array[Int]对应 Java 的int[]/Integer[]),支持通过下标快速访问元素(下标从 0 开始)。
核心特征:
- 长度不可变:一旦创建,数组长度无法修改(如需动态扩容,需使用
ArrayBuffer); - 元素可修改:通过下标
arr(index) = value修改元素值; - 泛型支持:可存储任意类型(值类型 / 引用类型),如
Array[Int]、Array[String]、Array[Any]。
定义方式:
scala
// 方式1:指定长度(初始值为默认值,Int默认0,String默认null)
val arr1: Array[Int] = new Array[Int](3) // 长度为3的Int数组,元素:[0,0,0]
// 方式2:直接初始化元素(最常用)
val arr2: Array[String] = Array("a", "b", "c") // 长度3,元素:["a","b","c"]
// 方式3:使用apply方法(简化写法,等价于方式2)
val arr3 = Array.apply(1, 2, 3) // Array[Int] = [1,2,3]
// 方式4:空数组
val arr4: Array[Nothing] = Array.empty
二、Array 的不可变与可变类型
Scala 中数组分为不可变 Array(默认)和可变 ArrayBuffer(动态数组),核心区别在于 “长度是否可修改”:
| 类型 | 核心特性 | 包路径 | 长度是否可变 | 适用场景 |
|---|---|---|---|---|
| 不可变 Array | 长度固定,元素可修改 | scala.Array(默认) | ❌ | 元素数量固定、需快速访问 |
| 可变 ArrayBuffer | 长度动态扩容 / 缩容,元素可修改 | scala.collection.mutable.ArrayBuffer | ✅ | 元素数量需动态增减 |
1. 不可变 Array(基础)
scala
val arr = Array(1, 2, 3)
arr(0) = 10 // 元素可修改,结果:[10,2,3]
// arr.length = 4 // 报错:长度不可修改
2. 可变 ArrayBuffer(动态数组)
需先导入包,支持+=/-=/++=等操作修改长度:
scala
import scala.collection.mutable.ArrayBuffer
// 创建ArrayBuffer
val buf = ArrayBuffer[Int](1, 2, 3)
// 新增元素
buf += 4 // 尾部加元素:[1,2,3,4]
buf += (5, 6) // 尾部加多个元素:[1,2,3,4,5,6]
buf ++= Array(7, 8) // 拼接数组:[1,2,3,4,5,6,7,8]
// 删除元素
buf -= 8 // 删除第一个8:[1,2,3,4,5,6,7]
buf.remove(0) // 删除下标0的元素:[2,3,4,5,6,7]
// 转换为不可变Array
val arr: Array[Int] = buf.toArray
三、Array 的常用方法
Scala 为Array提供了丰富的高阶方法(类似集合),核心方法分类如下:
| 类别 | 方法名 | 作用说明 |
|---|---|---|
| 基础操作 | length/size | 获取数组长度(等价,size是别名) |
apply(index)/arr(index) | 获取下标index的元素(apply是底层方法,arr(index)是语法糖) | |
update(index, value)/arr(index)=value | 修改下标index的元素值 | |
isEmpty/nonEmpty | 判断数组是否为空 / 非空 | |
| 遍历 / 转换 | foreach(f: T=>Unit) | 遍历每个元素并执行函数f |
map(f: T=>S) | 对每个元素应用函数f,返回新数组Array[S] | |
filter(p: T=>Boolean) | 过滤出满足条件的元素,返回新数组 | |
flatMap(f: T=>TraversableOnce[S]) | 扁平化映射(拆解嵌套数组) | |
toList/toSet/toBuffer | 转换为列表 / 集合 / ArrayBuffer | |
| 聚合操作 | sum/max/min | 求和 / 最大值 / 最小值(仅数值类型数组) |
foldLeft(init)(f)/reduce(f) | 聚合元素(foldLeft 需初始值,reduce 无初始值) | |
count(p: T=>Boolean) | 统计满足条件的元素个数 | |
| 查找 / 排序 | find(p: T=>Boolean) | 查找第一个满足条件的元素,返回Option[T] |
sortBy(f: T=>S) | 按指定字段排序(默认升序) | |
sorted | 按元素自身排序(数值升序、字符串字典序) | |
reverse | 反转数组元素顺序 |
常用方法示例:
scala
val arr = Array(1, 2, 3, 4, 5)
// 1. 基础操作
println(arr.length) // 5
println(arr(2)) // 3
arr(2) = 30 // 数组变为:[1,2,30,4,5]
// 2. 遍历
arr.foreach(println) // 依次输出1、2、30、4、5
// 3. 转换/过滤
val doubleArr = arr.map(_ * 2) // [2,4,60,8,10]
val evenArr = arr.filter(_ % 2 == 0) // [2,4]
// 4. 聚合
println(arr.sum) // 42(1+2+30+4+5)
println(arr.max) // 30
val sumReduce = arr.reduce(_ + _) // 42
// 5. 排序
val sortedArr = arr.sorted // [1,2,4,5,30]
val descArr = arr.sortBy(x => -x) // 降序:[30,5,4,2,1]
// 6. 查找
val findEven = arr.find(_ % 2 == 0) // Some(2)
四、多维数组 & grouped 方法
1. 多维数组(以二维数组为例)
Scala 的多维数组本质是 “数组的数组”,常见定义方式有两种:
方式 1:直接初始化(嵌套 Array)
scala
// 二维Int数组:2行3列
val twoDArr: Array[Array[Int]] = Array(
Array(1, 2, 3),
Array(4, 5, 6)
)
// 访问元素:行下标 + 列下标
println(twoDArr(0)(1)) // 2(第0行第1列)
// 遍历二维数组
twoDArr.foreach(row => row.foreach(println)) // 逐行输出1-6
方式 2:使用Array.ofDim(指定维度和长度)
scala
// 创建3行2列的二维数组(初始值为默认值)
val twoDArr2 = Array.ofDim[Int](3, 2) // [[0,0],[0,0],[0,0]]
twoDArr2(1)(0) = 10 // 修改为:[[0,0],[10,0],[0,0]]
// 三维数组(2层、3行、2列)
val threeDArr = Array.ofDim[String](2, 3, 2)
threeDArr(0)(1)(0) = "scala"
2. grouped方法
grouped(n: Int)是Array的核心方法,作用是将数组按指定长度n分组,返回迭代器Iterator[Array[T]] (惰性遍历,每组是一个子数组)。
核心特征:
- 分组规则:从左到右依次取
n个元素为一组,最后一组不足n个则保留剩余元素; - 返回值:迭代器(需遍历 / 转换为数组 / 列表才能查看结果)。
示例:
scala
val arr = Array(1, 2, 3, 4, 5, 6, 7)
// 1. 按长度3分组
val groupedIter: Iterator[Array[Int]] = arr.grouped(3)
// 2. 遍历迭代器(查看分组结果)
groupedIter.foreach(group => println(group.mkString(",")))
// 输出:
// 1,2,3
// 4,5,6
// 7
// 3. 转换为列表(一次性获取所有分组)
val groupedList = arr.grouped(3).toList
// groupedList = List(Array(1,2,3), Array(4,5,6), Array(7))
// 4. 结合多维数组:将一维数组转为二维数组
val twoDArrFromGrouped = arr.grouped(3).toArray
// twoDArrFromGrouped = Array(Array(1,2,3), Array(4,5,6), Array(7))
补充:sliding方法(与grouped对比)
sliding(n: Int, step: Int)是类似方法,意为 “滑动窗口”:
n:窗口长度,step:步长(默认 1);- 与
grouped的区别:grouped步长 = 窗口长度(不重叠),sliding可自定义步长(可重叠)。
scala
val arr = Array(1,2,3,4)
arr.sliding(2).toList // List(Array(1,2), Array(2,3), Array(3,4))(步长1,重叠)
arr.grouped(2).toList // List(Array(1,2), Array(3,4))(步长2,不重叠)
关键注意点
- 不可变
Array的 “不可变” 仅指长度,元素值可修改; - 多维数组的遍历需嵌套
foreach(行遍历 + 列遍历); grouped返回迭代器,遍历后会耗尽,需提前转换为数组 / 列表保存结果;- 如需动态修改数组长度,优先使用
ArrayBuffer而非Array。