scala学习之路(三)数组

数组相关操作

要点:

  1. 长度固定用Array,长度变化用ArrayBuffer
  2. 提供初始值时不要用new
  3. 用()来访问元素
  4. 用for(elem <-  arr来遍历元素)
  5. 用for(elem <- arr if ...) yield ... 来将原数组转型为新数组
  6. 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")
View Code

 

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

 

posted @ 2018-09-30 11:05  魏大大  阅读(1206)  评论(0编辑  收藏  举报