数组相关操作
要点:
- 长度固定用Array,长度变化用ArrayBuffer
- 提供初始值时不要用new
- 用()来访问元素
- 用for(elem <- arr来遍历元素)
- 用for(elem <- arr if ...) yield ... 来将原数组转型为新数组
- scala数组和java数组可以互相操作;用ArrayBuffer,使用scala.collection. JavaConversions中转换函数。
1.定长数组

val nums = new Array[Int](10) //10个整数的数组,初始化为0 val a = new Array[String](10) //10个元素的字符数组,初始化为null val s = Array("hello","world") //长度为2的数组——类型是推断出来的 当已经提供了初始值时,就不需要new了 s(0) = "aa" //访问数组 //Array("aa","world")
2.变长数组:数组缓冲
import scala.collection.mutable.ArrayBuffer
val b = ArrayBuffer[Int]() //一个空的数组缓冲,准备存放整数或者 ArrayBuffer[Int]
b += 1 //ArrayBuffer(1) 用+=在尾端添加元素
b += (1,2,3,4) //ArrayBuffer(1,1,2,3,4),在尾端添加多个元素,用括号包起来
b ++ = ArrayBuffer(8,13,21) //ArrayBuffer(1,1,2,3,4,8,13,21) 用++=操作符追加任何集合
b.trimEnd(5) //ArrayBuffer(1,1,2) 移除最后5个元素
b.insert(2,6) //在下标2之前插入
b.insert(2,7,8,9) //下标2之前插入7,8,9
b.remove(2) //移除2下标的元素
b.toArray //转为Array a.toBuffer将一个数组a转换为一个数组缓冲
3.遍历数组和数组缓冲
for(i <- 0 until a.length) println(s"$i: ${a(i)}")
//until方法跟to很像,只不过它排除了最后一个元素。变量i取值为从0到a.length-1
0 until a.length by 2 //设置步长 Range(0,2,4,...)
0 until a.length by -1 //从数组尾端开始遍历 Range(...,2,1,0)
//增强型遍历
for (elem <- a)
println(elem)
4.数组转换
从一个数组(或数组缓冲)出发,以某种方式对它进行转换,不会修改原始数组,而是交出一个全新的数组
val a = Array(2,3,5,7,11) val result = for(elem <-a ) yield 2 * elem // result是Array(4,6,19,14,22),原始集合没有受到影响
//另外一种做法:
a.filter(_ % 2 == 0).map(2 * _)
//或者
a.filter{ _ % 2 == 0} map {2 * _}
//高效的移除元素
传统的遍历移除元素并不搞高效,因为这个循环不必要地移动了后面会被移除的元素
方法一:scala中可以使用for/yield循环提取需要的元素
方法二:收集需要移除的元素位置,然后从后往前移除这些元素的位置
val position = for(i <- a.indices if a(i) < 0 ) yield i
for ( i <- position.reverse ) a.remove(i)
方法三:记住要保留的位置,将对应的元素(往前)复制,最后缩短缓冲
val position = for( i <- a.indices if a(i) >= 0) yield i
for(j<-position.indices) a(j) = a(position(j))
a.trimEnd(a.length - position.length)
5.常用算法
Array(1,2,3).sum //5 对ArrayBuffer同样适用 sum //方法元素类型必须是数值类型:整形、浮点数 min //取出数组或缓冲数组最小元素 max //取出数组或缓冲数组最大元素 sorted //排序并返回新的数组或缓冲数组,默认升序 sortWith(_>_) //降序 mkString //显示数组、缓冲数组内容, a.mkString("and") //指定分隔符 "1 and 2 and 3" a.mkString("<",",",">") //指定前缀后缀 "<1,2,3>" toString
6.解读Scaladoc
7.多维数组
多维数组是通过数组的数组来实现的
Double的二维数组为Array[Array[Double]]要构造这样一个数组,可以用ofDim方法
val matrix = Array.ofDim[Double](3,4) //三行四列
访问元素
matrix(row)(column) = 42
可以创建不规则的数组,每一行的长度各不相同
val t = new Array[Array[Int]](10)
for(i <- t.indices)
t(i) = new Array[Int](i+1)
8.与Java的互操作
由于Scala数组是用Java数组实现的,因此可以在Java和Scala之间来回传递
引入scala.collection.JavaConversions里的隐式转换方法。使用scala缓冲数组,在调用java方法时,这些对象会被自动包装成Java列表
java.util.ProcessBuilder类有一个以List<String>为参数的构造器。
在Scala中调用它的写法:
import scala.collection.JavaConversions.bufferAsJavaList
import scala.collection.mutable.ArrayBuffer
val command = ArrayBuffer("hello","world")
val pb = new ProcessBuilder(command) //scala到java的转换
scala缓冲被包装成了一个实现了java.util.List接口的Java类对象
反过来当Java方法返回java.util.List时,我们可以让它自动转换成一个Buffer
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
val cmd : Buffer[String] = pb.command() //Java到scala的转换
//不能使用ArrayBuffer——包装起来的对象仅能保证是一个Buffer
如果Java方法返回一个包装过的scala缓冲,那么隐式转换会将原始的对象解包出来。cmd == command