Scala學習之路 (四)Scala的數組、映射、元組、集合


一、數組

1、定長數組和變長數組

import scala.collection.mutable.ArrayBuffer

object TestScala {
  def main(args: Array[String]) {
    //初始化一個長度為8的定長數組,其所有元素均為0
    val arr1 = new Array[Int](8)
    //直接打印定長數組,內容為數組的hashcode值
    println("arr1="+arr1)
    //將數組轉換成數組緩沖,就可以看到原數組中的內容了
    //toBuffer會將數組轉換長數組緩沖
    println("arr1.toBuffer="+arr1.toBuffer)
    //注意:如果new,相當於調用了數組的apply方法,直接為數組賦值
    //初始化一個長度為1的定長數組
    val arr2 = Array[Int](10)
    println("arr2.toBuffer="+arr2.toBuffer)
    //定義一個長度為3的定長數組
    val arr3 = Array("hadoop", "storm", "spark")
    //使用()來訪問元素
    println("arr3(2)="+arr3(2))

    //////////////////////////////////////////////////
    //變長數組(數組緩沖)
    //如果想使用數組緩沖,需要導入import scala.collection.mutable.ArrayBuffer包
    var ab = ArrayBuffer[Int]()
    //向數組緩沖的尾部追加一個元素
    //+=尾部追加元素
    ab += 1
    //追加多個元素
    ab += (2, 3, 4, 5)
    //追加一個數組++=
    ab ++= Array(6, 7)
    //追加一個數組緩沖
    ab ++= ArrayBuffer(8,9)
    //打印數組緩沖ab

    //在數組某個位置插入元素用insert
    ab.insert(0, -1, 0)
    //刪除數組某個位置的元素用remove
    ab.remove(8, 2)
    println("ab="+ab)

  }

}

運行結果

2、遍歷數組

(1)增強for循環

(2)好用的until會生成腳標,0 until 10 包含0不包含10

 

def main(args: Array[String]) {
    //初始化一個數組
    val arr = Array(1,2,3,4,5,6,7,8)
    //增強for循環
    for(i <- arr)
      print(i+"\t")

    println()
    //好用的until會生成一個Range
    //reverse是將前面生成的Range反轉
    for(i <- (0 until arr.length).reverse)
      print(arr(i))
  }

3、數組轉換

yield關鍵字將原始的數組進行轉換會產生一個新的數組,原始的數組不變

def main(args: Array[String]) {
    //定義一個數組
    val arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
    //將偶數取出乘以10后再生成一個新的數組
    val res = for (e <- arr if e % 2 == 0) yield e * 10
    println(res.toBuffer)

    //更高級的寫法,用着更爽
    //filter是過濾,接收一個返回值為boolean的函數
    //map相當於將數組中的每一個元素取出來,應用傳進去的函數
    val r = arr.filter(_ % 2 == 0).map(_ * 10)
    println(r.toBuffer)

  }

4、常用數組的算法

在Scala中,數組上的某些方法對數組進行相應的操作非常方便!

二、映射(Map)

在Scala中,把哈希表這種數據結構叫做映射

1、構建映射

2、獲取映射中的值

getOrElse:有就返回對應的值,沒有就返回默認值

注意:在Scala中,有兩種Map,

一個是immutable包下的Map,Map中的內容不可變

另一個是mutable包下的Map,該Map中的內容可變 (val var)

注意:通常我們在創建一個集合是會用val這個關鍵字修飾一個變量(相當於java中的final),那么就意味着該變量的引用不可變,該引用中的內容是不是可變,取決於這個引用指向的集合的類型

1:是否可以修改值

Mutable  可以修改map里面的值

Immutable 不可以修改里面的值

2:是否可以追加元素

2.1  mutable var/val 都可以追加元素

2.2  imtable var 可以追加,val不可以追加

三、元組

映射是K/V對偶的集合,對偶是元組的最簡單形式,元組可以裝着多個不同類型的值。

1、創建元組

2、獲取元組中的值

3、將對偶的元組轉換成映射

4、拉鏈操作

zip命令可以將多個值綁定在一起

注意:如果兩個數組的元素個數不一致,拉鏈操作后生成的數組的長度為較小的那個數組的元素個數

四、集合

Scala 集合類系統地區分了可變的和不可變的集合。可變集合可以在適當的地方被更新或擴展。這意味着你可以修改,添加,移除一個集合的元素。而不可變集合類,相比之下,永遠不會改變。不過,你仍然可以模擬添加,移除或更新操作。但是這些操作將在每一種情況下都返回一個新的集合,同時使原來的集合不發生改變。

所有的集合類都可以在包scala.collection 或scala.collection.mutablescala.collection.immutablescala.collection.generic中找到。客戶端代碼需要的大部分集合類都獨立地存在於3種變體中,它們位於scala.collectionscala.collection.immutablescala.collection.mutable包。每一種變體在可變性方面都有不同的特征。

scala.collection.immutable包是的集合類確保不被任何對象改變。例如一個集合創建之后將不會改變。因此,你可以相信一個事實,在不同的點訪問同一個集合的值,你將總是得到相同的元素。

scala.collection.mutable包的集合類則有一些操作可以修改集合。所以處理可變集合意味着你需要去理解哪些代碼的修改會導致集合同時改變。

scala.collection包中的集合,既可以是可變的,也可以是不可變的。例如:collection.IndexedSeq[T]] 就是 collection.immutable.IndexedSeq[T] 和collection.mutable.IndexedSeq[T]這兩類的超類。scala.collection包中的根集合類中定義了相同的接口作為不可變集合類,同時,scala.collection.mutable包中的可變集合類代表性的添加了一些有輔助作用的修改操作到這個immutable 接口。

根集合類與不可變集合類之間的區別是不可變集合類的客戶端可以確保沒有人可以修改集合。然而,根集合類的客戶端僅保證不修改集合本身。即使這個集合類沒有提供修改集合的靜態操作,它仍然可能在運行時作為可變集合被其它客戶端所修改。

默認情況下,Scala 一直采用不可變集合類。例如,如果你僅寫了Set 而沒有任何加前綴也沒有從其它地方導入Set,你會得到一個不可變的set,另外如果你寫迭代,你也會得到一個不可變的迭代集合類,這是由於這些類在從scala中導入的時候都是默認綁定的。為了得到可變的默認版本,你需要顯式的聲明collection.mutable.Setcollection.mutable.Iterable.

一個有用的約定,如果你想要同時使用可變和不可變集合類,只導入collection.mutable包即可。

import scala.collection.mutable  //導入包scala.collection.mutable

然而,像沒有前綴的Set這樣的關鍵字, 仍然指的是一個不可變集合,然而mutable.Set指的是可變的副本(可變集合)。

集合樹的最后一個包是collection.generic。這個包包含了集合的構建塊。集合類延遲了collection.generic類中的部分操作實現,另一方面集合框架的用戶需要引用collection.generic中類在異常情況中。

為了方便和向后兼容性,一些導入類型在包scala中有別名,所以你能通過簡單的名字使用它們而不需要import。這有一個例子是List 類型,它可以用以下兩種方法使用,如下:

scala.collection.immutable.List // 這是它的定義位置
scala.List //通過scala 包中的別名
List // 因為scala._ // 總是是被自動導入。

下面的圖表顯示了scala.collection包中所有的集合類。這些都是高級抽象類或特性,它們通常具備和不可變實現一樣的可變實現。

下面的圖表顯示scala.collection.immutable中的所有集合類。

 

下面的圖表顯示scala.collection.mutable中的所有集合類。

 

Seq

不可變的序列 import scala.collection.immutable._

在Scala中列表要么為空(Nil表示空列表)要么是一個head元素加上一個tail列表。

9 :: List(5, 2)  :: 操作符是將給定的頭和尾創建一個新的列表

注意::: 操作符是右結合的,如9 :: 5 :: 2 :: Nil相當於 9 :: (5 :: (2 :: Nil))

def main(args: Array[String]): Unit = {
    //創建一個不可變集合
    val list1 = List(1,2,3)
    //將0插入到集合list1的前面生成一個新的list
    val list2 = 0 :: list1
    val list3 = list1.:: (0)
    val list4 = 0 +: list1
    val list5 = list1. +: (0)
    println("list2=" + list2)
    println("list3=" + list3)
    println("list4=" + list4)
    println("list5=" + list5)

    //將3插入到集合list1的后面生成一個新的list
    val list6 = list1 :+ 3
    println("list6="+list6)

    //將2個list集合合並成一個新的list集合
    val list0 = List(7,8,9)
    println("list0="+list0)
    val list7 = list1 ++ list0
    println("list7="+list7)

    //將list0插入到list1前面生成一個新的集合
    val list8 = list0 ++: list1
    println("list8="+list8)

    //將list1插入到list0前面生成一個新的集合
    val list9 = list1 ++: list0
    println("list9="+list9)

  }

可變的序列 import scala.collection.mutable._

def main(args: Array[String]): Unit = {
    //構建一個可變序列
    val list1 = ListBuffer[Int](1,2,3)
    //創建一個空的可變序列
    val list2 = new ListBuffer[Int]
    //向list2中追加元素,注意:沒有生成新的集合
    list2 += 6
    list2.append(7)
    println("list2=" + list2)

    //將list2中的元素追加到list1中,注意:沒有生成新的集合
    list1 ++= list2
    print("list1=" + list1)

    //將list1和list2合並成一個新的list集合,注意:生成新的集合
    val list3 = list1 ++ list2
    println("list3=" + list3)

    //將元素追加到list1后面生成一個新的集合
    val list4 = list1 :+ 9
    print("list4=" + list4)

  }

Set

不可變的Set

def main(args: Array[String]): Unit = {
    //創建一個空的set
    val set1 = new HashSet[Int]()
    println("set1=" + set1)
    //將元素和set合並生成一個新的set,原有set不變
    val set2 = set1 + 4
    println("set2=" + set2)
    //set中元素不能重復
    val set3 = set1 ++ Set(5,6,7)
    println("set3=" + set3)
    val set4 = Set(4,3,2) ++ set2
    println("set4=" + set4)
  }

可變的Set

def main(args: Array[String]): Unit = {
    //創建一個可變的set
    val set1 = new mutable.HashSet[Int]()
    println("list1=" + set1)
    //向set1中添加元素
    set1 += 4
    //add等價於+=
    set1.add(5)
    set1 ++= Set(6,7,8)
    println("set1="+set1)
    //刪除一個元素
    set1 -= 8
    set1.remove(7)
    println("set1=" + set1)

  }

 

 

 


免責聲明!

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



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