4.1 定长数组
在Scala中,如何定义一个长度不变的数组,可以用Scala中的Array来实现。例如:
//定义长度为10Int类型的数组,默认值为0
var nums = new Array[Int](10) //> nums : Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
// 定义长度为10的String类型数组,默认null
var str = new Array[String](10) //> str : Array[String] = Array(null, null, null, null, null, null, null, null,
//| null, null)
// 定义长度为2的数组,类型Scala自动识别
val words = Array("Scala", "Spark") //> words : Array[String] = Array(Scala, Spark)
// 将下标为1的值替换为HelloWorld
words(1) = “HelloWorld"
在JVM中,Scala的Array与Java中的数组方式基本相似,只是Scala会自动识别数组中值得类型,而Java中必须指定类型。
4.2 变长数组
变长数组也叫数组缓冲,开发中经常用到按需变化的数组,例如Java中的ArrayList,而在Scala中,则是ArrayBuffer。
在数组缓冲的末尾添加或移除元素是比较高效的操作,也可以在数组缓冲的任意位置添加或移除元素,但这种操作并不那么高效。
import scala.collection.mutable._
object ArrayBufferTest {
// main方法,这个和Java的main方法功能相似
def main(args : Array[String]) : Unit = {
// 空的数组缓冲,类型为Int
var b = ArrayBuffer[Int]() // 或者new ArrayBuffer[Int]
b += 1 // += 意思就是在数组缓冲末尾添加元素
println(b) // 结果:ArrayBuffer(1)
b += (2, 3, 4, 5)
println(b) // 结果: ArrayBuffer(1, 2, 3, 4, 5)
b ++= Array(10, 20, 30) // ++= 添加集合
println(b) // 结果:ArrayBuffer(1, 2, 3, 4, 5, 10, 20, 30)
b.trimEnd(3) // 移除后面添加的3个元素
println(b) // 结果:ArrayBuffer(1, 2, 3, 4, 5)
// 插入元素
b.insert(1, 100) // 在下标为1的地方插入元素100
println(b) // 结果: ArrayBuffer(1, 100, 2, 3, 4, 5)
b.insert(1, 200, 300, 400) // 数组下标为1的地方插入3个元素
println(b) // 结果:ArrayBuffer(1, 200, 300, 400, 100, 2, 3, 4, 5)
// 移除元素
b.remove(1) // 移除下标为1的元素
println(b) // 结果: ArrayBuffer(1, 300, 400, 100, 2, 3, 4, 5)
b.remove(1, 3) // 从下标为1处开始移除3个元素
println(b) // 结果:ArrayBuffer(1, 2, 3, 4, 5)
}
}
Array和ArrayBuffer之间的转换,可以用 toArray和toBuffer函数来转换。
4.3 遍历数组和数组缓冲
利用for循环遍历数组和缓冲数组,Scala相对Java来说,语法上有些不同,甚至更强大于Java。如下面的例子,例举了几种scala的for循环遍历语法:
object ForTest {
def main(args:Array[String]) : Unit = {
var array = Array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
/*
* 普通的for循环方式,与Java相似
* 其中 until 表示 array长度的区间,最大为 array.length - 1
* 实际上就是调用了until方法 0.until(array.length)
*/
for (index <- 0 until array.length) {
print(array(index) + " ")
}// 结果:10 20 30 40 50 60 70 80 90 100
println("******************************")
/*
* 不需要数组下标,这个是最常用的一种遍历方式
* 直接将元素赋值给index
*/
for (index <- array) {
print(index + " ")
}// 结果:10 20 30 40 50 60 70 80 90 100
println("******************************")
/*
* for循环,隔两个元素输出
*/
for (index <- 0 until (array.length, 2)) {
print(array(index) + " ")
}// 结果:10 30 50 70 90
println("******************************")
/*
* for循环,从数组的末端开始输出
*/
for (index <- (0 until array.length).reverse) {
print(array(index) + " ")
}// 结果:100 90 80 70 60 50 40 30 20 10
}
}
4.4 数组转换
可以使用for推导式,完成数组转换,产生一个全新的数组,例如:
object ForCoverter {
def main(args:Array[String]) : Unit = {
var a = Array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
// 推导式完成数组转换
var newA = for (elem <- a) yield elem * 2
// 在推导式中,你也可以加入判断条件来尽心过滤
var newB = for (elem <- a if elem > 50) yield elem * 2
// 输出newA的结果:20 40 60 80 100 120 140 160 180 200
for(index <- newA) print(index + " ")
println()
// 输出newB的结果:120 140 160 180 200
for(index2 <- newB) print(index2 + " ")
println()
/*
* filter方式的数组转换,这种方式虽然比较难理解,但是代码更加简洁
* _下划线表达遍历元素
*/
var newC = a.filter(_ > 50).map ( _ * 2)
for(index <- newC) print(index + " ")
}
}
4.5 常用算法
大多数时候,业务中经常会碰到求和以及排序,在scala中,有内建的函数进行处理。例如 Array(1, 3, 5, 7).sum,将数组里面的元素进行求和,当然前提元素的类型必须是数值类型:整形、浮点数或者BigInteger、BigDecimal。同理,min和max就是求数组或者数组缓冲里面的最小和最大元素。
sorted方法将数组或数组缓冲排序并返回经过排序的数组或数组缓冲
val s = ArrayBuffer(1, 9, 2, 5)
val sorted = s.sorted(_ > _)// 排序结果:9,5,2,1
或者:val sorted = s.sorted(_ < _) // 排序结果:1,2,5,9
数组的快速排序:
val a = Array(1, 5, 9, 2)
scala.util.Sorting.quickSort(a);
println(a.mkString(",")) // 输出结果:1,2,5,9
你可以直接对一个数组排序,但不能对数组缓冲排序,对于min,max和quickSort方法,元素类型必须支持比较操作,包括数字、字符串以及其他带有Ordered特质的类型。如果想要显示数组或数组缓冲的内容,可以用mkString方法,它允许指定元素之间的分隔符。