scala中的Array

54 阅读5分钟

一、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,不重叠)

关键注意点

  1. 不可变Array的 “不可变” 仅指长度,元素值可修改;
  2. 多维数组的遍历需嵌套foreach(行遍历 + 列遍历);
  3. grouped返回迭代器,遍历后会耗尽,需提前转换为数组 / 列表保存结果;
  4. 如需动态修改数组长度,优先使用ArrayBuffer而非Array