Scala 提供了一套很好的集合實現(xiàn),提供了一些集合類型的抽象。這讓你的代碼可以與 Foo 的集合交互,而無需擔(dān)心該集合是是一個 List,還是 Set,或是任何你有的類型。
這里提供了一個很好的頁面來查看各種集合的默認(rèn)實現(xiàn),并鏈接到他們的 scala 在線文檔。
標(biāo)準(zhǔn)的鏈表。
scala> List(1, 2, 3)
res0: List[Int] = List(1, 2, 3)
你可以用函數(shù)式語言的方式連接它們。
scala> 1 :: 2 :: 3 :: Nil
res1: List[Int] = List(1, 2, 3)
參考 API文檔
集沒有重復(fù)
scala> Set(1, 1, 2)
res2: scala.collection.immutable.Set[Int] = Set(1, 2)
參考 API文檔
序列有一個給定的順序。
scala> Seq(1, 1, 2)
res3: Seq[Int] = List(1, 1, 2)
(請注意返回的是一個列表。因為 Seq 是一個特質(zhì);而列表是序列的很好實現(xiàn)。如你所見,Seq 也是一個工廠單例對象,可以用來創(chuàng)建列表。)
參考 API文檔
映射是鍵值容器。
scala> Map('a' -> 1, 'b' -> 2)
res4: scala.collection.immutable.Map[Char,Int] = Map((a,1), (b,2))
參考 API文檔
下面介紹的都是特質(zhì),它們在可變的(mutable)和不可變的(immutable)的包中都有特定實現(xiàn)。
所有集合都可以被遍歷。這個特質(zhì)定義了標(biāo)準(zhǔn)函數(shù)組合子。 這些組合子根據(jù) foreach 來寫,所有集合必須實現(xiàn)。
參考 API文檔
iterator() 方法返回一個 Iterator 來迭代元素。
參考 API文檔
有順序的對象序列。
參考 API文檔
沒有重復(fù)的對象集合。
參考 API文檔
鍵值對。
參考 API文檔
下面所有方法在子類中都是可用的。參數(shù)和返回值的類型可能會因為子類的覆蓋而看起來不同。
def head : A
def tail : Traversable[A]
這里是函數(shù)組合子定義的地方。
def map [B] (f: (A) => B) : CC[B]
返回每個元素都被 f 轉(zhuǎn)化的集合
def foreach[U](f: Elem => U): Unit
在集合中的每個元素上執(zhí)行 f 。
def find (p: (A) => Boolean) : Option[A]
返回匹配謂詞函數(shù)的第一個元素
def filter (p: (A) => Boolean) : Traversable[A]
返回所有匹配謂詞函數(shù)的元素集合
劃分:
def partition (p: (A) ? Boolean) : (Traversable[A], Traversable[A])
按照謂詞函數(shù)把一個集合分割成兩部分
def groupBy [K] (f: (A) => K) : Map[K, Traversable[A]]
轉(zhuǎn)換:
有趣的是,你可以轉(zhuǎn)換集合類型。
def toArray : Array[A]
def toArray [B >: A] (implicit arg0: ClassManifest[B]) : Array[B]
def toBuffer [B >: A] : Buffer[B]
def toIndexedSeq [B >: A] : IndexedSeq[B]
def toIterable : Iterable[A]
def toIterator : Iterator[A]
def toList : List[A]
def toMap [T, U] (implicit ev: <:<[A, (T, U)]) : Map[T, U]
def toSeq : Seq[A]
def toSet [B >: A] : Set[B]
def toStream : Stream[A]
def toString () : String
def toTraversable : Traversable[A]
把映射轉(zhuǎn)換為一個數(shù)組,您會得到一個鍵值對的數(shù)組。
scala> Map(1 -> 2).toArray
res41: Array[(Int, Int)] = Array((1,2))
添加一個迭代器的訪問。
def iterator: Iterator[A]
一個迭代器能給你提供什么?
def hasNext(): Boolean
def next(): A
這是非常 Java 式的。你通常不會看到在 Scala 中使用迭代器,通常更容易出現(xiàn)的是函數(shù)組合器或 for 循環(huán)的使用。
def contains(key: A): Boolean
def +(elem: A): Set[A]
def -(elem: A): Set[A]
通過鍵查找的鍵值對的序列。
可以像這樣將一個鍵值對列表傳入 apply()
scala> Map("a" -> 1, "b" -> 2)
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,1), (b,2))
或者像這樣:
scala> Map(("a", 2), ("b", 2))
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,2), (b,2))
什么是->?
這不是特殊的語法,這是一個返回元組的方法。
scala> "a" -> 2
res0: (java.lang.String, Int) = (a,2)
請記住,這僅僅是下面代碼的語法糖
scala> "a".->(2)
res1: (java.lang.String, Int) = (a,2)
您也可以使用++
操作符構(gòu)建
scala> Map.empty ++ List(("a", 1), ("b", 2), ("c", 3))
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,1), (b,2), (c,3))
HashSet 和 HashMap 的快速查找,這些集合的最常用的形式。 HashSet API, HashMap API
TreeMap 是 SortedMap 的一個子類,它可以讓你進(jìn)行有序訪問。 [TreeMap API]()
Vector 快速隨機選擇和快速更新。 Vector API
scala> IndexedSeq(1, 2, 3)
res0: IndexedSeq[Int] = Vector(1, 2, 3)
Range 等間隔的 Int 有序序列。你經(jīng)常會在 for 循環(huán)看到。 Range API
scala> for (i <- 1 to 3) { println(i) }
1
2
3
Ranges 支持標(biāo)準(zhǔn)的函數(shù)組合子。
scala> (1 to 3).map { i => i }
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3)
使用特質(zhì)的 apply 方法會給你默認(rèn)實現(xiàn)的實例,例如,Iterable(1, 2)會返回一個列表作為其默認(rèn)實現(xiàn)。
scala> Iterable(1, 2)
res0: Iterable[Int] = List(1, 2)
序列 Seq 也是一樣的,正如我們前面所看到的
scala> Seq(1, 2)
res3: Seq[Int] = List(1, 2)
scala> Iterable(1, 2)
res1: Iterable[Int] = List(1, 2)
scala> Sequence(1, 2)
warning: there were deprecation warnings; re-run with -deprecation for details
res2: Seq[Int] = List(1, 2)
Set
scala> Set(1, 2)
res31: scala.collection.immutable.Set[Int] = Set(1, 2)
IndexedSeq 快速隨機訪問元素和一個快速的長度操作。"API 文檔":http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html
LinearSeq 通過 head 快速訪問第一個元素,也有一個快速的 tail 操作。 API 文檔
不可變
優(yōu)點
缺點
Scala 允許我們是務(wù)實的,它鼓勵不變性,但不懲罰我們需要的可變性。這和 var vs. val 非常相似。我們總是先從 val 開始并在必要時回退為 var。
我們贊成使用不可改變的版本的集合,但如果性能使然,也可以切換到可變的。使用不可變集合意味著你在多線程不會意外地改變事物。
前面討論的所有類都是不可變的。讓我們來討論常用的可變集合。
HashMap 定義了 getOrElseUpdate
, +=
HashMap API
scala> val numbers = collection.mutable.Map(1 -> 2)
numbers: scala.collection.mutable.Map[Int,Int] = Map((1,2))
scala> numbers.get(1)
res0: Option[Int] = Some(2)
scala> numbers.getOrElseUpdate(2, 3)
res54: Int = 3
scala> numbers
res55: scala.collection.mutable.Map[Int,Int] = Map((2,3), (1,2))
scala> numbers += (4 -> 1)
res56: numbers.type = Map((2,3), (4,1), (1,2))
您可以通過 JavaConverters package 輕松地在 Java 和 Scala 的集合類型之間轉(zhuǎn)換。它用 asScala 裝飾常用的 Java 集合以和用 asJava 方法裝飾 Scala 集合。
import scala.collection.JavaConverters._
val sl = new scala.collection.mutable.ListBuffer[Int]
val jl : java.util.List[Int] = sl.asJava
val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
assert(sl eq sl2)
雙向轉(zhuǎn)換:
scala.collection.Iterable <=> java.lang.Iterable
scala.collection.Iterable <=> java.util.Collection
scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set <=> java.util.Set
scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap
此外,也提供了以下單向轉(zhuǎn)換
scala.collection.Seq => java.util.List
scala.collection.mutable.Seq => java.util.List
scala.collection.Set => java.util.Set
scala.collection.Map => java.util.Map
更多建議: