1.定长数组
如果你需要一个长度不变的始祖,可以使用Scala中的Array。例如:
var arr1 = new Array[Int](10) //10个整数的数组,所有元素初始化为0。通过简化apply(10)方法实现
var arr2 = new Array[String](10) //10个元素的字符串数组,所有元素初始化为null。
var arr3 = Array("Hello","World") //长度为2的Array[String]——类型是推断出来的,已经提供初始值就不需要new
arr3(0) = "Goodbye" //Array["Goodbye","World"],使用()而不是[]来访问元素
2.变长数组:数组缓冲
对于那种长度有变化的数组,Java有ArrayList,C++有vector。Scala中有等效的数据结构ArrayBuffer。
import scala.collection.mutable.ArrayBuffer
val b = ArrayBuffer[Int]()
//一个空的ArrayBuffer,准备添加整数
//或者new ArrayBuffer[Int]
b += 1
//ArrayBuffer(1)
//用+=在尾端添加元素
b += (1,2,3,4,5)
//ArrayBuffer(1, 1, 2, 3, 4, 5)
//在尾端添加多个元素
b ++= Array(8,13,21)
//ArrayBuffer(1, 1, 2, 3, 4, 5, 8, 13, 21)
//你可以用++=操作符追加任何集合
b.trimEnd(5)
//ArrayBuffer(1, 1, 2, 3)
//移除最后5个元素
b.trimStart(2)
//ArrayBuffer( 2, 3)
//移除开头2个元素
在数组缓冲的尾端添加或移除元素是一个高效的操作。
-----------------------------------
你也可以在任意位置插入或移除元素,但这样的操作并不搞笑——所有在那个位置之后的元素都必须被平移。例如:
b.insert(开始坐标,插入元素...)
b.remove(开始坐标,移除个数)
-----------------------------------
另外,边长数组与定长数组可以相互转换
b.toArray //变长转定长
a.toBuffer //定长转变长
3.遍历数组和数组缓冲
for循环遍历
for(i <- 0 until a.length) println(a(i))
注:until 是RichInt类的方法,返回所有小于但不包括上限的数字。
-----------------------------------
如果想要每两个元素一跳,可以这样进行遍历
for(i <- 0 until (a.length,2) ) println(a(i))
-----------------------------------
如果要从数组尾端开始,遍历的写法为:
for(i <- (0 until a.length).reverse) println(a(i))
-----------------------------------
入伏哦在循环体中不需要用到数组下标,我们也可以直接访问数组元素:
for(elem <- a) println(elem)
这个和Java中的增强for循环很相似。
4.数组转换
1.for推导式
for(...) yield循环创建了一个类型与原始集合相同的新集合。不论数组还是数组缓冲,你得到的都将是新的数组或数组缓冲。
for(i <- 1 to 10) yield 2 * i
2.通过守卫
通常,你变里一个集合时,你只想处理那些满足条件的元素,这个需求可以通过守卫:for中的if实现。在这里我们对每个偶数翻倍,并去掉奇数元素:
for(i <- 1 to 10 if i % 2 == 0) yield 2 * i
说明:另一种做法是
var a =Array(1 to 10:_*)
a.filter(_ % 2 == 0).map(2 * _) 甚至 a.filter{_ % 2 == 0}.map{2 * _}
5.常用算法
sum 数组或数组缓冲求和
max 数组或数组缓冲返回最大值
min 数组或数组缓冲返回最小值
sorted 对数组或数组缓冲排序,返回一个新的数组或数组缓冲
源码中有两点值得注意的地方:
1.sorted方法中有个隐式参数ord: Ordering。
2.sorted方法真正排序的逻辑是调用的java.util.Arrays.sort。
-----------------------------------
你可以对一个数组排序,但不能对数组缓冲区排序:
import scala.util.Sorting._
val a = Array(1,4,3,2)
quickSort(a) //a现在是(1,2,3,4)
-----------------------------------
最后,如果你想要显示数组或数组缓冲的内容,可以使用mkString方法,它允许你指定元素间的分隔符,还有一个重载版本可以指定前缀后缀:
6.多维数组
和Java一样,多维数组是通过数组的数组来实现的。举例来说,Double的二维数组类型为Array[Array[Double]]。要构造这样的一个数组,可以用ofDim方法:
要访问其中的元素,需要使用两个()圆括号
你也可以创建不规则的数组,每一行长度各不相同:
多维数组的遍历:
单层遍历:
双层遍历:
7.Scala数组与Java数组相互转换
由于Scala数组使用Java数组实现的,我们可以在Java和Scala之间来回传递
比如,我们可以在Scala中使用Java的集合
或者
-----------------------------------
我们可以在将Scala变长数组,赋值给Java集合,这需要我们导入包来支持:
import scala.collection.JavaConversions.bufferAsJavaList
反之,我们也可以将刚才的Java集合转换成Scala的Buffer,这是我们需要导入包:
import scala.collection.JavaConversions.asScalaBuffer
但是,从Java的集合转换成Scala的变长数组,不能使用ArrayBuffer来作为入参类型,需要用父类Buffer来作为入参对象
注:使用Java的集合类时,指定类型必须定义泛型,不返回报错,并且这种转换只针对Scala变长数组与Java的集合之间,数组不支持
注:Scala中的泛型是放在[]中的,这里与Java不一样