【Scala 教程】Scala 集合類型

作者:夢家
個人站點:dreamhomes.top
公衆號:DreamHub

Scala Collection

Scala提供了一套很好的集合實現,提供了一些集合類型的抽象。

Scala 集合分爲可變的和不可變的集合:

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

常用集合類型:

  • Scala List(列表):List的特徵是其元素以線性方式存儲,集合中可以存放重複對象。
  • Scala Set(集合):Set是最簡單的一種集合。集合中的對象不按特定的方式排序,並且沒有重複對象。
  • Scala Map(映射):Map 是一種把鍵對象和值對象映射的集合,它的每一個元素都包含一對鍵對象和值對象。
  • Scala 元組:元組是不同類型的值的集合
  • Scala Option:Option[T] 表示有可能包含值的容器,也可能不包含值。
  • Scala Iterator(迭代器):迭代器不是一個容器,更確切的說是逐一訪問容器內元素的方法。

下面將說明這六種集合類型,在jupyter中查看效果更佳哦!傳送門~

List 列表

Scala 列表類似於數組,它們所有元素的類型都相同,但是它們也有所不同:列表是不可變的,值一旦被定義了就不能改變,其次列表具有遞歸的結構(也就是鏈接表結構)而數組不是。

// 字符串列表
val name: List[String] = List("Shen", "Meng", "Jia")
name
// 整型列表
val nums: List[Int] = List(1, 2, 3, 4)
nums
// 空列表
val empty: List[Nothing] = List()
// 二維列表
val dim: List[List[Int]] =
   List(
      List(1, 0, 0),
      List(0, 1, 0),
      List(0, 0, 1)
   )
dim

PS:構造列表的兩個基本單位是 Nil::Nil 也可以表示爲一個空列表。上述定義可以重新寫爲:

// 字符串列表
val site = "Shen" :: ("Meng" :: ("Jia" :: Nil))
val site_simple= "Shen" :: "Meng":: "Jia"::Nil

// 整型列表
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
val nums_simple = 1 :: 2 :: 3 :: 4 :: Nil
// 空列表
val empty = Nil

// 二維列表
val dim = (1 :: (0 :: (0 :: Nil))) ::
          (0 :: (1 :: (0 :: Nil))) ::
          (0 :: (0 :: (1 :: Nil))) :: Nil

PS:對於::操作符的解釋:該操作被稱爲 cons,意爲構造,向隊列的頭部追加數據創造新的列表。用法爲 x::list,其中 x 爲加入到頭部的元素,無論 x是列表與否,它都只將成爲新生成列表的第一個元素,length+1。(btw, x::list等價於list.::(x))

val site1 = "dreamhomes" :: "Google" :: "Baidu" :: Nil
val site2 = "Facebook" :: "Taobao" :: Nil

// 使用 :: 運算符
println("site::site2"+site1::site2)
println("site::site2"+site1.::(site2))
// 使用 ::: 運算符
var fruit = site1 ::: site2
println( "site1 ::: site2 : " + fruit )

// 使用 List.:::() 方法
fruit = site1.:::(site2)
println( "site1.:::(site2) : " + fruit )

// 使用 concat 方法
fruit = List.concat(site1, site2)
println( "List.concat(site1, site2) : " + fruit  )
List(site::site2List(dreamhomes, Google, Baidu), Facebook, Taobao)
site::site2List(List(Facebook, Taobao), dreamhomes, Google, Baidu)
site1 ::: site2 : List(dreamhomes, Google, Baidu, Facebook, Taobao)
site1.:::(site2) : List(Facebook, Taobao, dreamhomes, Google, Baidu)
List.concat(site1, site2) : List(dreamhomes, Google, Baidu, Facebook, Taobao)

列表基本操作

Scala列表有三個基本操作:

  • head 返回列表第一個元素
  • tail 返回一個列表,包含除了第一元素之外的其他元素
  • isEmpty 在列表爲空時返回true
val name = "Shen"::"Meng"::"JIa"::Nil
val nums = Nil

println( "第一元素是 : " + name.head )
println( "最後元素是 : " + name.tail )
println( "查看列表 site 是否爲空 : " + name.isEmpty )
println( "查看 nums 是否爲空 : " + nums.isEmpty )
第一元素是 : Shen
最後元素是 : List(Meng, JIa)
查看列表 site 是否爲空 : false
查看 nums 是否爲空 : true

對於列表操作方法很多,可以參考語法教程:Scala List

Set 集合

Scala Set(集合)是沒有重複的對象集合,所有的元素都是唯一的。

Scala 集合分爲可變的和不可變的集合。

默認情況下,Scala 使用的是不可變集合,如果你想使用可變集合,需要引用 scala.collection.mutable.Set 包。

// 不可變set
val set = Set(1,2,3)
println(set.getClass.getName)

println(set.exists(_ % 2 == 0))
println(set.drop(1))
scala.collection.immutable.Set$Set3
true
Set(2, 3)
// 可變 set
import scala.collection.mutable.Set // 可以在任何地方引入 可變集合

val mutableSet = Set(1,2,3)
println(mutableSet.getClass.getName) // scala.collection.mutable.HashSet

mutableSet.add(4)
mutableSet.remove(1)
mutableSet += 5
mutableSet -= 2

println(mutableSet) 

val another = mutableSet.toSet
println(another.getClass.getName) // scala.collection.immutable.Set
scala.collection.mutable.HashSet
HashSet(3, 4, 5)
scala.collection.immutable.Set$Set3

PS:雖然可變Set和不可變Set都有添加或刪除元素的操作,但是有一個非常大的差別。對不可變Set進行操作,會產生一個新的set,原來的set並沒有改變,這與List一樣。 而對可變Set進行操作,改變的是該Set本身,與ListBuffer類似。

操作方法參考 Scala Sets

Map 映射

Map(映射)是一種可迭代的鍵值對(key/value)結構。所有的值都可以通過鍵來獲取。Map 中的鍵都是唯一的。

Map 也叫哈希表(Hash tables),與python中的字典類似。

默認情況下 Scala 使用不可變 Map。如果你需要使用可變集合,你需要顯式的引入 import scala.collection.mutable.Map 類。在 Scala 中 你可以同時使用可變與不可變 Map,不可變的直接使用 Map,可變的使用 mutable.Map

// 空哈希表,鍵爲字符串,值爲整型
var A:Map[Char,Int] = Map()

// Map 鍵值對演示
val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")
//定義 Map 時,需要爲鍵值對定義類型。如果需要添加 key-value 對,可以使用 + 號
A += ('I' -> 1)
A += ('J' -> 5)
A
// Map 訪問
val colors = Map("red" -> "#FF0000",
               "azure" -> "#F0FFFF",
               "peru" -> "#CD853F")

val nums: Map[Int, Int] = Map()

println( "colors 中的鍵爲 : " + colors.keys )
println( "colors 中的值爲 : " + colors.values )
println( "檢測 colors 是否爲空 : " + colors.isEmpty )
println( "檢測 nums 是否爲空 : " + nums.isEmpty )

println("檢測是否包含鍵值red:" + colors.contains("red"))

println("輸出鍵值對:")
colors.keys.foreach{ i =>  
                           print( "Key = " + i )
                           println(" Value = " + colors(i))}
colors 中的鍵爲 : Set(red, azure, peru)
colors 中的值爲 : Iterable(#FF0000, #F0FFFF, #CD853F)
檢測 colors 是否爲空 : false
檢測 nums 是否爲空 : true
檢測是否包含鍵值red:true
輸出鍵值對:
Key = red Value = #FF0000
Key = azure Value = #F0FFFF
Key = peru Value = #CD853F

PS:=>表示匿名函數,(形參列表) => {函數體},例如:(x:Int) => x +1 等同於 lambda x:x+1

其它操作方法參考:Scala Map

Tuple 元組

與列表一樣,元組也是不可變的,但與列表不同的是元組可以包含不同類型的元素。

元組的值是通過將單個的值包含在圓括號中構成的。

val t = (1, 3.14, "Fred") 
//val t1 = new Tuple3(1, 3.14, "Fred")

//訪問元組中的元素
println(t._1 + t._2)

// 迭代輸出
t.productIterator.foreach{ i =>println("Value = " + i )}
4.140000000000001
Value = 1
Value = 3.14
Value = Fred

更多操作參考:Scala Tuple3

Option 選項

Scala Option(選項)類型用來表示一個值是可選的(有值或無值)。

Option[T] 是一個類型爲 T 的可選值的容器: 如果值存在, Option[T] 就是一個 Some[T] ,如果不存在, Option[T] 就是對象 None

Option 有兩個子類別,一個是 Some,一個是 None,當他回傳 Some 的時候,代表這個函式成功地給了你一個 String,而你可以透過 get() 這個函式拿到那個 String,如果他返回的是 None,則代表沒有字符串可以給你。

val myMap: Map[String, String] = Map("key1" -> "value")
val value1: Option[String] = myMap.get("key1")
val value2: Option[String] = myMap.get("key2")
 
value1
value2
// 可以通過模式匹配來輸出匹配值
def show(x: Option[String]) = x match {
  case Some(s) => s
  case None => "?"
}
show(value1)
show(value2)

更多操作方法參考:Scala Option

Iterator 迭代器

Scala Iterator(迭代器)不是一個集合,它是一種用於訪問集合的方法。

迭代器 it 的兩個基本操作是 next 和 hasNext:

  • 調用 it.next() 會返回迭代器的下一個元素,並且更新迭代器的狀態。
  • 調用 it.hasNext() 用於檢測集合中是否還有元素。

讓迭代器 it 逐個返回所有元素最簡單的方法是使用 while 循環。

val it = Iterator("Baidu", "Google", "Dreamhomes", "Taobao")

while (it.hasNext){
 println(it.next())
}
Baidu
Google
Dreamhomes
Taobao

更多方法參考:Scala Iterator

聯繫作者

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章