天天看點

Scala集合的mutable和immutable解釋概述集合API概述

Scala集合的mutable和immutable解釋

  • 概述
  • 集合API概述

概述

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

    總結:

    可變集合可以修改,添加,移除

    不可變集合永遠不會改變,但是可以模拟添加,移除和更新操作,傳回的都是新集合

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

    總結:

    經常使用的Scala的API基本位于以下三個包中:

    頂級父類/根集合: scala.collection

    不可變集合:scala.collection.immutable

    可變集合:scala.collection.mutable

  3. scala.collection.immutable包是的集合類確定不被任何對象改變。例如一個集合建立之後将不會改變。是以,你可以相信一個事實,在不同的點通路同一個集合的值,你将總是得到相同的元素。

    總結:

    如果通路的是immutable包中的一個集合對象,該集合将不會改變,集合中的元素也不會更改,模拟更改操作得到的結果是一個新集合

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

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

  5. 根集合類與不可變集合類之間的差別是不可變集合類的用戶端可以確定沒有人可以修改集合。然而,根集合類的用戶端僅保證不修改集合本身。即使這個集合類沒有提供修改集合的靜态操作,它仍然可能在運作時作為可變集合被其它用戶端所修改。
  6. 預設情況下,Scala 一直采用不可變集合類。例如,如果你僅寫了Set 而沒有任何加字首也沒有從其它地方導入Set,你會得到一個不可變的set,另外如果你寫疊代,你也會得到一個不可變的疊代集合類,這是由于這些類在從scala中導入的時候都是預設綁定的。為了得到可變的預設版本,你需要顯式的聲明collection.mutable.Set或collection.mutable.Iterable.

    總結:

    預設使用不可變的集合,若要使用可變集合,請導入可變集合

    一個有用的約定,如果你想要同時使用可變和不可變集合類,隻導入collection.mutable包即可。
    import scala.collection.mutable  //導入包scala.collection.mutable
                    
    然而,像沒有字首的Set這樣的關鍵字, 仍然指的是一個不可變集合,然而mutable.Set指的是可變的副本(可變集合)。
  7. 集合樹的最後一個包是collection.generic。這個包包含了集合的建構塊。集合類延遲了collection.generic類中的部分操作實作,另一方面集合架構的使用者需要引用collection.generic中類在異常情況中。

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

    scala.collection.immutable.List // 這是它的定義位置
    scala.List //通過scala 包中的别名
    List // 因為scala._     // 總是是被自動導入。
                    
    其它類型的别名有: Traversable, Iterable, Seq, IndexedSeq, Iterator, Stream, Vector, StringBuilder, Range。
  8. 下面的圖表顯示了scala.collection包中所有的集合類。這些都是進階抽象類或特性,它們通常具備和不可變實作一樣的可變實作。
    Scala集合的mutable和immutable解釋概述集合API概述
  9. 下面的圖表顯示scala.collection.immutable中的所有集合類。
    Scala集合的mutable和immutable解釋概述集合API概述
  10. 下面的圖表顯示scala.collection.mutable中的所有集合類。
    Scala集合的mutable和immutable解釋概述集合API概述
    (以上三個圖表由Matthias生成, 來自decodified.com)。

集合API概述

大多數重要的集合類都被展示在了上表。而且這些類有很多的共性。例如,每一種集合都能用相同的文法建立,寫法是集合類名緊跟着元素。

Traversable(1, 2, 3)
Iterable("x", "y", "z")
Map("x" -> 24, "y" -> 25, "z" -> 26)
Set(Color.red, Color.green, Color.blue)
SortedSet("hello", "world")
Buffer(x, y, z)
IndexedSeq(1.0, 2.0)
LinearSeq(a, b, c)
                

相同的原則也應用于特殊的集合實作,例如:

List(1, 2, 3)
HashMap("x" -> 24, "y" -> 25, "z" -> 26)
                

所有這些集合類都通過相同的途徑,用toString方法展示出來。

Traversable類提供了所有集合支援的API,同時,對于特殊類型也是有意義的。例如,Traversable類 的map方法會傳回另一個Traversable對象作為結果,但是這個結果類型在子類中被重寫了。例如,在一個List上調用map會又生成一個List,在Set上調用會再生成一個Set,以此類推。

scala> List(1, 2, 3) map (_ + 1)
res0: List[Int] = List(2, 3, 4)
scala> Set(1, 2, 3) map (_ * 2)
res0: Set[Int] = Set(2, 4, 6)
           

在集合類庫中,這種在任何地方都實作了的行為,被稱之為傳回類型一緻原則。

大多數類在集合樹中存在這于三種變體:root, mutable 和immutable。唯一的例外是緩沖區特征,它僅在于mutable集合。