Scala 提供了一套很好的集合实现,提供了一些集合类型的抽象。这让你的代码可以与 Foo 的集合交互,而无需担心该集合是是一个 List,还是 Set,或是任何你有的类型。
这里提供了一个很好的页面来查看各种集合的默认实现,并链接到他们的 scala 在线文档。
标准的链表。
scala> List(1, 2, 3) |
res0: List[Int] = List(1, 2, 3) |
scala> 1 :: 2 :: 3 :: Nil |
res1: List[Int] = List(1, 2, 3) |
集没有重复
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) |
参考 API文档
映射是键值容器。
scala> Map('a' -> 1, 'b' -> 2) |
res4: scala.collection.immutable.Map[Char,Int] = Map((a,1), (b,2)) |
参考 API文档
下面介绍的都是特质,它们在可变的(mutable)和不可变的(immutable)的包中都有特定实现。
所有集合都可以被遍历。这个特质定义了标准函数组合子。 这些组合子根据 foreach 来写,所有集合必须实现。
参考 API文档
iterator() 方法返回一个 Iterator 来迭代元素。
参考 API文档
有顺序的对象序列。
参考 API文档
没有重复的对象集合。
参考 API文档
键值对。
参考 API文档
下面所有方法在子类中都是可用的。参数和返回值的类型可能会因为子类的覆盖而看起来不同。
def head : A |
def tail : Traversable[A] |
def map [B] (f: (A) => B) : CC[B] |
def foreach[U](f: Elem => U): Unit |
def find (p: (A) => Boolean) : Option[A] |
def filter (p: (A) => Boolean) : Traversable[A] |
划分:
def partition (p: (A) ⇒ Boolean) : (Traversable[A], Traversable[A]) |
def groupBy [K] (f: (A) => K) : Map[K, Traversable[A]] |
有趣的是,你可以转换集合类型。
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] |
scala> Map(1 -> 2).toArray |
res41: Array[(Int, Int)] = Array((1,2)) |
添加一个迭代器的访问。
def iterator: Iterator[A] |
def hasNext(): Boolean |
def next(): A |
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) |
++
操作符构建
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 的一个子类,它可以让你进行有序访问。 [TreeMap API]()
Vector 快速随机选择和快速更新。 Vector API
scala> IndexedSeq(1, 2, 3) |
res0: IndexedSeq[Int] = Vector(1, 2, 3) |
scala> for (i <- 1 to 3) { println(i) } |
1 |
2 |
3 |
scala> (1 to 3).map { i => i } |
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3) |
使用特质的 apply 方法会给你默认实现的实例,例如,Iterable(1, 2)会返回一个列表作为其默认实现。
scala> Iterable(1, 2) |
res0: Iterable[Int] = List(1, 2) |
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) |
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 文档
不可变
优点
缺点
Scala 允许我们是务实的,它鼓励不变性,但不惩罚我们需要的可变性。这和 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 的集合类型之间转换。它用 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) |
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 |
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 |