知識點:
1.定長數組 Array
val nums = new Array[Int](10) //10個整數的數組,所有元素初始化為0 val a = new Array[String](10) //10個元素的字符串數組,所有元素初始化為null val s= Array("Hello","World") //長度為2的Array(String) 類型是編譯器推斷出來的,已提供初始值就不需要new s(0) = "Goodbye" //Array("Google","World") 使用()而不是[]來訪問元素
Scala的Array以Java數組方式實現,例子中的s對應的是java.lang.String[]
2.變長數組:數組緩沖 ArrayBuffer
對於長度按需要變化的數組,Java-ArrayList || C++-vector || Scala-ArrayBuffer
val b = ArrayBuffer[Int]() //或者 new ArrayBuffer[Int] b += 1 //ArrayBuffer(1) 用 += 在尾端添加元素 b += (1,2,3,4,5) //ArrayBuffer(1,1,2,3,4,5) 在尾端添加多個元素,用括號包起來 b ++= Array(6,7,8) //ArrayBuffer(1,1,2,3,4,5,6,7,8) 用 ++= 追加任何集合 b.trimEnd(5) //ArrayBuffer(1,1,2,3)移除最后5個元素
在數組緩沖的尾部添加或移除元素是一個高效的操作。也可以在任意位置插入和刪除元素,這樣的操作不高效,引發位置后的元素都必須被平移。
b.insert(2, 9) //ArrayBuffer(1,1,9,2,3) b.insert(2, 10,11) //ArrayBuffer(1,1,10,11,9,2,3) b.remove(2) //ArrayBuffer(1,1,11,9,2,3) b.remove(2,3) //ArrayBuffer(1,1,3)
有時候你需要構建一個Array,但不知道元素有多少個,可以先構建ArrayBuffer,再調用b.toArray();反過來,調用a.toBuffer可以將一個數組a轉換為一個數組緩沖。
3.遍歷數組和數組緩沖
for(i <- 0 until a.length) //變量i值從0取到a.length-1 println(i + ": " + a(i))
for(i <- 區間) 會讓i遍歷區間所有值。
0 until (a.length, 2) //Range(0,2,4,6,...) 每兩個元素一跳 (0 until a.length).reverse //Range(...,3,2,1,0) 逆序 for(elem <- a) //不使用數組下標時 println(elem)
3.數組轉換
val aa = Array(2,5,8,9) val result = for(elem <- aa) yield 2 * elem //result是Array(4,10,16,18)
for(…) yield 循環創建了一個類型與原始集合相同的新集合。結果包含yield之后的表達式,每次迭代對應一個。當你遍歷一個集合時,你只想處理那些滿足特定條件的元素,可以通過 守衛 :for 中的 if 實現。
for(elem <- aa if elem % 2 == 0) yield 2 * elem //另一種實現方法
a.filter(_ % 2 == 0).map(2 * _) a.filter{ _ % 2 == 0} map { 2 * _}
4.常用方法
sum\max\sorted sum方法的數組元素類型必須是數值類型,sorted方法將數組或緩沖數組排序后返回經過排序的數組或緩沖數組,不修改原始版本。
顯示數組或緩沖數組的內容,可以用mkString方法。
5.多維數組是通過數組的數組實現的
val matrix = Array.ofDim[Double](3,4) matrix(row)(column) = 42 //創建不規則的數組 val triangle = new Array[Array[Int]](10) for(i <- 0 until triangle.length) triangle(i) = new Array[Int](i+1)
練習:(答案源鏈接)
1.編寫一段代碼,將a設置為一個n個隨機整數的數組,要求隨機數介於0(包含)和n(不包含)之間
class test{ def main(args:Array[Int]){ getArr(10).foreach(println) } def getArr(n:Int): Array[Int] = { val a = new Array[Int](n) val rand = new scala.util.Random() for(i <- a) yield rand.nextInt() } }
2.編寫一個循環,將整數數組中相鄰的元素置換
class test{ def main(args:Array[Int]){ val arr = Array(1,2,3,4,5) revert(arr) arr.foreach(println) } def revert(a:Array[Int]) = { for(i <- 0 until (a.length - 1,2)){ val t = a(i) a(i) = a(i+1) a(i+1) = t } } }
3.重復前一個練習,不過這次生成一個新的值交換過的數組。用for/yield。
class test{ def main(args:Array[Int]){ val a = Array(1,2,3,4,5) val b = revertYield(a) b.foreach(println) } def revertYield(a:Array[Int]) = { for(i <- 0 until a.length) yield { if( i < (a.length - 1) && i % 2 == 0){ //偶數下標時,則交換下一個相鄰的元素值 val t = a(i) a(i) = a(i+1) a(i+1) = t } a(i) //因為生成新的數組,每一個元素都要返回 } } }
4.給定一個整數數組,產出一個新的數組,包含元數組中的所有正值,以原有順序排列,之后的元素是所有零或負值,以原有順序排列。
import scala.collection.mutable.ArrayBuffer class test{ def main(args:Array[Int]){ val a = Array(1,-2,0,4,5,0,-3) val b = reCombine(a) b.foreach(println) } def reCombine(a:Array[Int]) = { val buf = new ArrayBuffer[Int](); buf ++= (for( i <- a if(i > 0)) yield i) buf ++= (for( i <- a if(i == 0 || i < 0)) yield i) buf.toArray } }
5.如何計算Array[Double]的平均值?
class test{ def main(args:Array[Int]){ val a = Array(1.0,5.6,0.0,-3.0) val b = average(a) println(b) } def average(a:Array[Double]) = { var t = 0.0 for(i <- a){ t += i } t/a.length } def ave(a:Array[Double]) = { a.sum / a.length } }
6.如何重新組織Array[Int]的元素將它們反序排列?對於ArrayBuffer[Int]你又會怎么做呢?
import scala.collection.mutable.ArrayBuffer object Hello { def main(args: Array[String]) { val a = Array(1,2,3,4,5) reverseArray(a) println("array reverse:") a.foreach(println) val b = a.reverse //將a的值逆序回去了 b.foreach(println) println("bufferArray reverse:") val c = ArrayBuffer(6,7,8,9,0); val d = c.reverse d.foreach(println) } def reverseArray(a:Array[Int]) = { for( i <- 0 until (a.length / 2)){ val t = a(i) a(i) = a(a.length-1-i) a(a.length-1-i)=t } } }
7.編寫一段代碼,產出數組中的所有值,去掉重復項
import scala.collection.mutable.ArrayBuffer object Hello { def main(args: Array[String]) { val ab = new ArrayBuffer[Int]() val c = new ArrayBuffer[Int]() println("Input the array line,separated by a space,ended with an enter.") val input = readLine().toString().split(' '); for(i <- input){ ab += i.toInt } // ab.foreach(println) c ++= ab.distinct c.foreach(println) } }
8.重新編寫3.4節結尾的示例。收集負值元素的下標,反序,去掉最后一個下標,然后對每一個下標調用a.remove(i)。比較這樣做的效率和3.4節中另外兩種方法的效率
import scala.collection.mutable.ArrayBuffer object Hello { def main(args: Array[String]) { val a = ArrayBuffer(1,2,4,-2,0,-1,-4,8) deleteNeg(a) a.foreach(println) } def deleteNeg(a:ArrayBuffer[Int]) = { val indexes = for(i <- 0 until a.length if a(i) < 0 ) yield i //不能val b = indexex.reverse.trimEnd(1) reverse后,它是一個Seq序列。 //value trimEnd is not a member of scala.collection.immutable.IndexedSeq[Int] val b = new ArrayBuffer[Int]() b ++= indexes.reverse b.trimEnd(1) //remove是ArrayBuffer的函數,如果傳入的是Array,則需要調用toBuffer for(i <- b){ a.remove(i) } } }
9.創建一個由java.util.TimeZone.getAvailableIDs返回的時區集合,判斷條件是它們在美洲,去掉”America/“前綴並排序。
import scala.collection.mutable.ArrayBuffer import scala.collection.JavaConversions.asScalaBuffer object Hello { def main(args: Array[String]) = { var c = timeZoneName() c.foreach(println) } def timeZoneName() = { val arr = java.util.TimeZone.getAvailableIDs(); val tmp = (for (i <- arr if i.startsWith("America/")) yield { i.drop("America/".length) }) scala.util.Sorting.quickSort(tmp) tmp } }
10.引入java.awt.datatransfer._並構建一個類型為SystemFlavorMap類型的對象,然后以DataFlavor.imageFlavor為參數調用getNativesForFlavor方法,以Scala緩沖保存返回值。
import scala.collection.JavaConversions.asScalaBuffer import scala.collection.mutable.Buffer import java.awt.datatransfer._ object Hello { def main(args: Array[String]) = { val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap] val buf : Buffer[String] = flavors.getNativesForFlavor(DataFlavor.imageFlavor); buf.foreach(println); } }