Scala数组
简介
- Scala 语言中提供的数组是用来存储固定大小的同类型元素,数组对于每一门编辑应语言来说都是重要的数据结构之一。
- 声明数组变量并不是声明 number0、number1、...、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。
- 数组的第一个元素索引为0,最后一个元素的索引为元素总数减1。
定长数组
如果你需要一个长度不变的数组,可以用Scala中的Array。例如:
//10个整数的数组,所有元素初始化为0
val nums = new Array[Int](10)
//10个元素的字符串数组,所有元素初始化为null
val a = new Array[String](10)
//长度为2的Array[String]数组————类型是推断出来的
//注意:已提供初始化值就不需要new了
val s = Array("Hello","World")
//使用()而不是[]来访问数组内元素
s(0) = "Goodbye"
在JVM中,Scala的Array以Java数组方式实现。示例中数组在JVM中的类型为java.lang.String[]。Int、Double或其他与Java中基本类型对应的数组都是基本类型数组。
变长数组
对于那种长度按需要变化的数组,Java提供ArrayList,C++提供Vector。Scala中的等效数据结构为ArrayBuffer。
import scala.collection.mutable.ArrayBuilder
//创建一个空的数组缓存,准备存放整数
val b: ArrayBuffer[Int] = ArrayBuffer[Int]()
// 或者
val b: ArrayBuffer[Int] = new ArrayBuffer[Int]
//用+=在尾端添加元素
b += 1
//结果:ArrayBuffer(1)
//在尾端添加多个元素,以括号抱起来
b +=(1, 2, 3, 5)
//结果:ArrayBuffer(1,1,2,3,5)
//你可以用++=操作符追加任何集合
b ++= Array(8, 13, 21)
//结果:ArrayBuffer(1,1,2,3,5,8,13,21)
//移除最后5个元素
b.trimEnd(5)
//结果:ArrayBuffer(1,1,2)
你也可以在任意位置插入或移除元素,但这样的操作并不那么高效——所有在那个位置之后的元素都必须被平移。举例如下:
val b = new ArrayBuffer[Int]()
b +=(1, 1, 2)
//在下标2之前插入元素6
b.insert(2, 6)
//结果:ArrayBuffer(1,1,6,2)
//你可以插入任意多的元素
b.insert(2, 7, 8, 9)
//结果:ArrayBuffer(1,1,7,8,9,6,2)
//移除下标为2的元素
b.remove(2)
//结果:ArrayBuffer(1,1,8,9,6,2)
//从下标为2开始,移除3个元素
b.remove(2, 3)
//结果:ArrayBuffer(1,1,2)
//有时你需要构建一个Array,但不知道最终需要装多少个元素。这种情况下,先构建一个数组缓冲,然后调用toArray得到这个Array。
b.toArray
//结果:Array(1,1,2)
遍历数组和数组缓冲
使用for循环遍历数组或数组缓冲:
//创建一个空的数组缓存,准备存放整数
val b: ArrayBuffer[Int] = ArrayBuffer[Int]()
b +=(1, 2, 3, 5)
//for循环遍历数组
for (i <- 0 until b.length) {
println(i + " : " + b(i))
}
变量i的取值从0到a.length -1
Until是RichInt类的方法,返回所有小于(但不包含)上限的数字。例如:
0 until 10
//表示:0,1,2,3,4,5,6,7,8,9
如果想要每两个元素一跳,可以让i这样来遍历:
for (i <- 0 until(10, 2))
print(i + " ")
//0 2 4 6 8
如果想从尾端开始遍历,可以这样:
for (i <- (0 until(10, 2)).reverse)
print(i + " ")
//8 6 4 2 0
数组转换
Scala可以像Java或C++那样操作数组。不过在Scala中,你可以走的更远。从一个数组(或数组缓冲)出发,以某种方式对它进行转换时很简单的。这些转换动作不会修改原始数组,而是产生一个全新的数组。
像这样使用for推倒式:
val a = Array(2, 3, 5, 7, 11)
val result = for (elem <- a) yield 2 * elem
//result是Array(4,6,10,14,22
注意:result是一个新的集合,原始集合没有受到影响
上述操作另一种写法:
a.filter(_ % 2 == 0).map(2 * _)
数组内操作函数
数组求和:
val a = Array(2, 13, 25, 7, 11).sum
println(a)
//结果为:58
//对ArrayBUffer
min和max输出数组或数组缓冲中最小和最大元素。
ArrayBuffer("Mary","had","a","little","lamb").max
//”little”
Sorted方法将数组或数组缓冲排序并返回结果排序的数组或数组缓冲,这个过程并不会修改原始版本:
val b = ArrayBuffer(1, 7, 2, 9).toArray
scala.util.Sorting.quickSort(b)
//结果:1 2 7 9
如果你想要显示数组或数组缓冲的内容,可以使用mkString方法,它允许你指定元素之间的分隔符。
val b = ArrayBuffer(1, 7, 2, 9).mkString(" and ")
print(b)
//结果:1 and 7 and 2 and 9
或者
val b = ArrayBuffer(1, 7, 2, 9).mkString("<",",",">")
print(b)
//结果:<1,7,2,9>
多维数组
和Java一样,多维数组是通过数组的数组实现的。举例来说,Double的二维数组类型为Array[Array[Double]]。要构造这样一个数组,可以用ofDim方法。
val matrix = Array.ofDim[Double](3,4) //三行,四列
//要访问其中的元素,使用两对圆括号:
matrix(row)(column) = 42
你可以创建不规则的数组,每一行的长度各不相同:
val triangle = new Array[Array[Int]](10)
for(i <- 0 until triangle.length) {
triangle(i) = new Array[Int](i+1)
二维数组示例:
object exam1 {
def main(args: Array[String]): Unit = {
var myMatrix = Array.ofDim[Int](3, 3)
// 创建矩阵
for (i <- 0 to 2) {
for (j <- 0 to 2) {
myMatrix(i)(j) = j;
}
}
// 打印二维阵列
for (i <- 0 to 2) {
for (j <- 0 to 2) {
print(" " + myMatrix(i)(j));
}
println();
}
}
}