1. 程式人生 > >scala筆記-Array、ArrayBuffer以及遍歷陣列(7)

scala筆記-Array、ArrayBuffer以及遍歷陣列(7)

Array

在Scala中,Array代表的含義與Java中類似,也是長度不可改變的陣列。此外,由於Scala與Java都是執行在JVM中,雙方可以互相呼叫,因此Scala陣列的底層實際上是Java陣列。
例如字串陣列在底層就是Java的String[],整數陣列在底層就是Java的Int[]。

// 陣列初始化後,長度就固定下來了,而且元素全部根據其型別初始化
val a = new Array[Int](10)
a(0)
a(0) = 1
val a = new Array[String](10)

// 可以直接使用Array()建立陣列,元素型別自動推斷
val a = Array("hello", "world")
a(0) = "hi"
val a = Array("leo", 30)
ArrayBuffer

在Scala中,如果需要類似於Java中的ArrayList這種長度可變的集合類,則可以使用ArrayBuffer。

// 如果不想每次都使用全限定名,則可以預先匯入ArrayBuffer類
import scala.collection.mutable.ArrayBuffer
// 使用ArrayBuffer()的方式可以建立一個空的ArrayBuffer
val b = ArrayBuffer[Int]()
// 使用+=操作符,可以新增一個元素,或者多個元素
// 這個語法必須要謹記在心!因為spark原始碼裡大量使用了這種集合操作語法!
b += 1
b += (2, 3, 4, 5)
// 使用++=操作符,可以新增其他集合中的所有元素
b ++= Array(6, 7, 8, 9, 10)
// 使用trimEnd()函式,可以從尾部截斷指定個數的元素
b.trimEnd(5)

// 使用insert()函式可以在指定位置插入元素
// 但是這種操作效率很低,因為需要移動指定位置後的所有元素
b.insert(5, 6)
b.insert(6, 7, 8, 9, 10)
// 使用remove()函式可以移除指定位置的元素
b.remove(1)
b.remove(1, 3)
// Array與ArrayBuffer可以互相進行轉換
b.toArray
a.toBuffer
遍歷Array和ArrayBuffer
// 使用for迴圈和until遍歷Array / ArrayBuffer
// 使until是RichInt提供的函式
for (i <- 0 until b.length)
  println(b(i))
// 跳躍遍歷Array / ArrayBuffer
for(i <- 0 until (b.length, 2))
  println(b(i))
// 從尾部遍歷Array / ArrayBuffer
for(i <- (0 until b.length).reverse)
  println(b(i))
// 使用“增強for迴圈”遍歷Array / ArrayBuffer
for (e <- b)
  println(e)
陣列常見操作
// 陣列元素求和
val a = Array(1, 2, 3, 4, 5)
val sum = a.sum
// 獲取陣列最大值
val max = a.max
// 對陣列進行排序
scala.util.Sorting.quickSort(a)
// 獲取陣列中所有元素內容
a.mkString
a.mkString(", ")
a.mkString("<", ",", ">")
// toString函式
a.toString
b.toString

使用yield和函數語言程式設計轉換陣列
// 對Array進行轉換,獲取的還是Array
val a = Array(1, 2, 3, 4, 5)
val a2 = for (ele <- a) yield ele * ele
// 對ArrayBuffer進行轉換,獲取的還是ArrayBuffer
val b = ArrayBuffer[Int]()
b += (1, 2, 3, 4, 5)
val b2 = for (ele <- b) yield ele * ele
// 結合if守衛,僅轉換需要的元素
val a3 = for (ele <- if ele % 2 == 0) yield ele * ele

// 使用函數語言程式設計轉換陣列(通常使用第一種方式)
a.filter(_ % 2 == 0).map(2 * _)
a.filter { _ % 2 == 0 } map { 2 * _ }
演算法案例:移除第一個負數之後的所有負數
// 構建陣列
val a = ArrayBuffer[Int]()
a += (1, 2, 3, 4, 5, -1, -3, -5, -9)

// 每發現一個第一個負數之後的負數,就進行移除,效能較差,多次移動陣列
var foundFirstNegative = false
var arrayLength = a.length
var index = 0
while (index < arrayLength) {
  if (a(index) >= 0) {
    index += 1
  } else {
    if (!foundFirstNegative) { foundFirstNegative = true; index += 1 }
    else { a.remove(index); arrayLength -= 1 }
  }
}

演算法案例:移除第一個負數之後的所有負數(改良版)

// 重新構建陣列
val a = ArrayBuffer[Int]()
a += (1, 2, 3, 4, 5, -1, -3, -5, -9)

// 每記錄所有不需要移除的元素的索引,稍後一次性移除所有需要移除的元素
// 效能較高,陣列內的元素遷移只要執行一次即可
var foundFirstNegative = false
val keepIndexes = for (i <- 0 until a.length if !foundFirstNegative || a(i) >= 0) yield {
  if (a(i) < 0) foundFirstNegative = true
  i
}
for (i <- 0 until keepIndexes.length) { a(i) = a(keepIndexes(i)) }
a.trimEnd(a.length - keepIndexes.length)
多維陣列
/構造行與列的二維陣列
//3指外層有3個數組,4指每個陣列有四個元素 即:3行4列
val multiDimArr1=Array.ofDim[Double](3,4)
multiDimArr1(0)(0) = 1.0
//構造不規則多維陣列
//指外層有三個陣列
val multiDimArr2 =new Array[Array[Int]](3)
//第二個陣列有1個元素
multiDimArr2(0)=new Array[Int](1)
//第一個陣列有2個元素
multiDimArr2(1)=new Array[Int](2)
//第三個陣列有3個元素
multiDimArr2(2)=new Array[Int](3)

//scala程式碼中直接呼叫JDK(java)API,比如呼叫一個java類的方法,勢必可能會傳入java型別的list
//Scala中構造出來的list,其實是ArrayBuffer,直接將scala的ArrayBuffer傳入java接收的ArrayList,肯定不行
import scala.collection.JavaConversions.bufferAsJavaList
import scala.collection.mutable.ArrayBuffer

val command =ArrayBuffer("javac","C:\\Users\\A...\\HelloWorld.java")
val processBuilder =new ProcessBuilder(command)
val process=processBuilder.start()
val res =process.waitFor()

import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer

val cmd:Buffer[String]=processBuilder.command()