Scala入門學習筆記三--數組使用


前言

本篇主要講Scala的Array、BufferArray、List,更多教程請參考: Scala教程

本篇知識點概括

  • 若長度固定則使用Array,若長度可能有 變化則使用ArrayBuffer
  • 提供初始值時不要使用new,復雜對象數組沒有提供初始值時必須提供new
  • 用()來訪問元素
  • 用for(elem <- arr)來遍歷數組
  • 用for(elem <- arr if...)...yield...來將原數組轉型為新數組
  • Scala數組和Java數組可以互操作

數組

1、定長數組定義:

//定義一個長度為10的數值數組
scala> val numberArray = new Array[int](10)
numberArray:Array[Int] = Array(0,0,0,0,0,0,0,0,0,0)
//定義一個長度為10的String類數組
scala> val strArray = new Array[String](10)
strArray:Array[String] = Array(null, null, null, null, null, null, null, null, null, null)

//由上可以看出,復雜對象類型在數組定義時被初始化為null,數值型唄初始化為0,並且上面復雜類型定義的時候必須加new,否則會報錯

//提供初始值的定義數組
scala> val strArray2 = Array("First", "Second")  //這里說明已提供初始值就不需要new
strArray2:Array[String] = Array(First, Second)

scala> strArray2(0) = "Goodbye"
strArray2:Array[String] = Array(Goodbye, Second)

2、變長數組定義
對於長度需要變化的數組,Java有ArrayList,C++有vector。Scala中的等效數據結構為ArrayBuffer

//導入可變包,Scala中的可變集合都是放在mutable中,使用時要導入
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val arrayBuffer = ArrayBuffer[Int]()
arrayBuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

//在尾部添加一個值
scala> arrayBuffer += 1
res17: arrayBuffer.type = ArrayBuffer(1)

//在尾部添加多個元素
scala> arrayBuffer += (2, 3, 4, 5)
res19: arrayBuffer.type = ArrayBuffer(1, 2, 3, 4, 5)

//在尾部添加一個集合
scala> arrayBuffer ++= Array(6, 7, 8, 9)
res20: arrayBuffer.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)

//移除最后2個元素
scala> arrayBuffer.trimEnd(2)

//在開頭移除1一個元素
scala> arrayBuffer.trimStart(2)

scala> arrayBuffer
res23: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 3, 4, 5, 6, 7)


//在任意位置插入或者刪除元素
scala> arrayBuffer.insert(2, 6)
//ArrayBuffer(2, 3, 6, 4, 5, 6, 7)

scala> arrayBuffer.insert(1, 2, 3, 4)
//ArrayBuffer(2, 1, 2, 3, 4, 3, 6, 4, 5, 6, 7)

scala> arrayBuffer.remove(2)
//ArrayBuffer(2, 1, 3, 4, 3, 6, 4, 5, 6, 7)

scala> arrayBuffer.remover(1, 8)
//ArrayBuffer(2, 7)

3、變長數組和定長數組轉換

//變長轉換長定長
scala > arrayBuffer.toArray
//Array(2, 7)

//定長轉換成變長
scala>res7.toBuffer
//ArrayBuffer(2, 7)

4、遍歷定長和變長數組

for(i <- 0 until.arrayBuffer.length)
    println(i + ": " + a(i))

0 until.arrayBuffer.length實際上是一個方法調用,返回的是一個區間Range: 0.until(arrayBuffer.length)
for(i <- 區間)會讓變量i遍歷該區間的所有值
如果想要在區間中步長不為1,則:0 until (arrayBuffer.length, 2)
如果想要數組從尾端開始,則遍歷的寫法為:(0 until (arrayBuffer.length, 2)).reverse

Scala也提供了一個和Java增強for循環類似的for ``` //增強for for(i <- arrayBuffer) println(i + ": " + a(i)) ```

5、數組轉換
《Scala入門學習筆記二-基本數據類型、程序控制結構》提到在for循環推導式,可以利用原來的數組產生一個新的數組。

scala> val a = Array(2, 3, 5, 7, 11)
a: Array[Int] = Array(2, 3, 5, 7, 11)
//這里產生了一個新的數組,原來的數組也在
scala> val result = for(elem <- a) yield 2 * elem
result: Array[Int] = Array(4, 6, 10, 14, 22)

如果for中使用的是定長數組,則for(...)...yield之后得到的是定長數組;如果使用的是變長數組,則會得到變長數組

  • Scala也提供了另外一種做法
scala> a.filter(_ % 2 == 0).map(2 * _)

甚至
scala>a.filter(_ % 2 == 0).map{2 * _}

例子:
給定一個整數的緩沖數組,我們想要移除第一個負數之外的所有負數。有幾種做法

//第一種做法:
var first = true
var n = a.length
var i = 0
while(i < n){
    if(a(i) > 0) i += 1
    else{
        if(first) {first = false; i += 1}
        else {a.remove(i); n-= 1}
    }
}

//第二種做法:
//首先使用一個新數組用於記錄滿足條件的數組的下標
val first = true
val indexes = for(i <- 0 until a.length if first || a(i) > 0) yield {
    if(a(i) < 0) first = false; i
}
//然后將元素移動到該去的位置,截斷尾端
for(j <- o until indexes.length) a(j) = a(indexes(j))
a.trimEnd(a.length-indexes.length)

6、常用算法
Scala針對數組提供了一個常用的函數

//定義一個整型數組
scala> val intArr=Array(1,2,3,4,5,6,7,8,9,10)
intArr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

//求和
scala> intArr.sum
res87: Int = 55

//求最大值
scala> intArr.max
res88: Int = 10

scala> ArrayBuffer("Hello","Hell","Hey","Happy").max
res90: String = Hey

//求最小值
scala> intArr.min
res89: Int = 1

//排序
//sorted方法將數組或數組緩沖排序並返回經過排序的數組或數組緩沖,原始數組被保留
scala>val b = ArrayBuffer(1, 7, 2, 9)
b:ArrayBuffer[Int] = ArrayBuffer(1, 7, 2, 9)
scala>val bSorted = b.sorted(_<_) 
bSorted: ArrayBuffer[Int] = ArrayBuffer(1, 2, 7, 9)

//toString()方法
scala> intArr.toString()
res94: String = [I@141aba8

//mkString()方法
scala> intArr.mkString(",")
res96: String = 1,2,3,4,5,6,7,8,9,10

scala> intArr.mkString("<",",",">")
res97: String = <1,2,3,4,5,6,7,8,9,10>

7、ArrayBuffer Scaladoc解析
初學者在查看sacaladoc時常常會感到困惑,不用擔心,隨着學習的深入,api文檔中的內容將逐漸清晰
下面給出兩個示例:
++=方法傳入的參數類型是TraversableOnce Trait的子類,它返回的是更新好的ArrayBuffer

++=方法解析

dropWhile傳入的是一個函數,該函數返回值是布爾類型,dropWhile反回的是操作后的ArrayBuffer

dropWith方法解析

8、多維數組
和Java一樣,多維數組是通過數組的數組來實現的。

//第一種構造方式
val metrix = Array.ofDim[Double](3, 4) //3行 4列

//訪問其中的元素
metrix(row)(column)  =42

//可以創建不規則的數組,每一行的長度不相同
val triangle = new Array[Array[Int]](10)
for(i <- 0 until triangle.length)
    trianglr(i) = new Array[Int](i+1)

//在創建的時候賦值
scala> val metrix = Array(Array(1, 2, 3), Array(2.3, 3.4), Array("asdf", "asdfas"))
metrix: Array[Array[_ >: String with Double with Int]] = Array(Array(1, 2, 3), Array(2.3, 3.4), Arra
y(asdf, asdfas))

//打印輸出數組
scala> for(i <- metrix) println(i.mkString(" "))
1 2 3
2.3 3.4
asdf asdfas

//輸出二維數組的每個值
scala> for(i <- metrix; from = i; j <- from) println(j)
1
2
3
2.3
3.4
asdf
asdfas


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM