14-使用其他集合類

前言

本節介紹除List之外的其他集合類型,如Set、Map。

1. 序列

序列類型可以用來處理依此排列分組的數據。由於元素是有次序的,所以可以使用下標如1、2、3…等訪問。

  1. 列表
    如果看過《13-使用列表》,應該對列表比較熟悉了,這裏使用一個簡單例子:
    在這裏插入圖片描述

  2. 數組
    在這裏插入圖片描述
    衆多的方法:
    在這裏插入圖片描述

  3. 列表緩衝(list buffer)
    ListBuffer是看一遍對象,在需要追加元素來構建列表時更加高效。
    使用 += 往後追加,使用 +=: 往前追加。
    如:
    在這裏插入圖片描述

  4. 數組緩衝(ArrayBuffer)
    在這裏插入圖片描述

  5. 字符串(StringOps)
    StringOps實現了很多序列方法。由於Predef有一個從String到StringOps的隱式轉換,可以將任何字符串當作序列處理,如:
    在這裏插入圖片描述
    字符串本身並沒有"exists"方法,Scala編譯器會隱式地將s 轉換成StringOps,在StringOps 中有exists方法。exists方法將字符串當做字符序列。

2. 集和映射

在Scala中默認的Set和Map是不可變類型。如果需要使用可變類型,需要引入。如果直接引入可變類型的類名,將會覆蓋不可變類型。所以,通常是引入可變類型所在包的包名,如:
在這裏插入圖片描述

集裏的每一個對象最多出現一次,如下面例子:統計字符串中出現的不同的單詞。
將字符串單詞分割出來:
17.1.scala

// 統計不同單詞
val text = "Hello world. Hello scala!"
val wordsArr = text.split("[ !,.]+")	// 參數爲正則表達式

在這裏插入圖片描述
由於集可以自動過濾重複項,所以只需要把分割的單詞加入集即可:
17.1.scala

// 創建空集
val words = mutable.Set.empty[String]
for (word <- wordsArr) {
  words += word.toLowerCase
}
words

在這裏插入圖片描述
其他操作:(手機拍攝不是很清晰)
在這裏插入圖片描述

映射

可變映射的基本操作:
在這裏插入圖片描述
例子,統計字符串中每個單詞出現的次數:
17.1.scala

def countWords(text: String) = {
  val counts = mutable.Map.empty[String, Int]
  for (rawWord <- text.split("[ ,!.]+")) {
    val oldCount = {
      if (counts.contains(rawWord)) counts(rawWord)
      else 0
    }
    // 計數
    counts += (rawWord -> (oldCount + 1))
  }
  counts
}

在這裏插入圖片描述
常用方法:
在這裏插入圖片描述
在這裏插入圖片描述

默認的集和映射

對於可變集合映射,返回對象內部都使用到了哈希表。返回對象分別爲HashSet 和 HashMap。因爲使用到了哈希表,所以可以很快判斷某個對象是否在集合中。

對於不可變集合而言,相對較複雜。
對於少於5個元素的集,有各自對應的返回對象,5個及以上返回HashSet和HashMap,如:
在這裏插入圖片描述
在這裏插入圖片描述
測試:
在這裏插入圖片描述
單獨的對象能夠帶來最佳的性能。

排好序的集和映射

Scala集合類庫提供了SortedSet 和 SortedMap 特質。這些特質被TreeSet和TreeMap類實現。如:
在這裏插入圖片描述

3. 在可變和不可變集合類之間選擇

Scala支持可變和不可變集合,但是更加推薦不可變集合。
當然,Scala也支持可變與不可變集合之間的相互轉換。
如,不可變集合映射並不真正支持 += 操作,但Scala提供了一個變通的解讀:只要看到 a += b,而a 並不支持名爲 += 的方法,Scala會嘗試把它解讀爲 a = a + b。
測試:
在這裏插入圖片描述
這樣操作你會發現報錯。原因就是:不可變Set 沒有 += 方法,所以Scala 編譯器會翻譯爲 aset = aset + 4。但是,aset 是val 不可修改變量,所以會報錯。因此,你可能猜到可以使用var 變量:
在這裏插入圖片描述
同理,-=、- -=、++=操作也是一樣的。

4. 初始化集合

相信簡單的初始化你已經沒有問題,下面介紹其他初始化方法。

  1. 從List 初始化
    不能直接傳入一個列表對象。
    在這裏插入圖片描述
    需要創建空的TreeSet,使用 ++ 將列表元素添加:
    在這裏插入圖片描述
    其中, ++ 後面跟多個元素,+ 後面跟一個元素。

  2. 轉成數組或列表
    在這裏插入圖片描述
    注意:這裏轉換後的元素是有序的。

  3. 在可變和不可變集和映射間轉換
    這裏用一個示例:把TreeSet轉換爲可變集,然後把可變集轉爲不可變集。
    在這裏插入圖片描述
    注意,這裏轉換後是無序的。
    同樣,也可以將不可變轉換爲可變類型:
    在這裏插入圖片描述

5. 元組

元組不同於列表和數組,元組可以存放不同類型的元素,如:
在這裏插入圖片描述
示例,尋找字符串第一個最長字母及下標:
17.1.scala

// 尋找字符串第一個最長字母及下標
def longest(words: Array[String]) = {
  var word = words(0)
  var idx = 0
  for (i <- 1 until words.length) {
    if (words(i).length > word.length) {
      word = words(i)
      idx = i
    }
  }
  (word, idx)
}
longest("Life is short, I use Python.".split("[ ,.]"))

在這裏插入圖片描述
關於元組的一些操作:
在這裏插入圖片描述
解元組(模式匹配的一個特例):
這裏有加不加括號的區別。
在這裏插入圖片描述

完!

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