The Collections Library
17.1 Hierarchy (2.13+/Scala 3)
scala.collection.immutable — default (imported automatically).
scala.collection.mutable — ArrayBuffer, ListBuffer, HashMap, HashSet, Queue, Stack, ArrayDeque, PriorityQueue, StringBuilder.
Iterable
├── Seq
│ ├── IndexedSeq: Vector, ArraySeq, Range, String (via wrapper)
│ └── LinearSeq: List, LazyList, Queue
├── Set: HashSet, TreeSet (SortedSet), ListSet, BitSet
└── Map: HashMap, TreeMap (SortedMap), ListMap, VectorMap17.2 List (immutable singly linked)
val xs = List(1, 2, 3)
0 :: xs // prepend O(1): List(0, 1, 2, 3)
xs :+ 4 // append O(n)
xs ++ List(4, 5)
xs.head, xs.tail, xs.last, xs.init
xs.isEmpty, xs.length
Nil // empty list
List.fill(3)("x"), List.range(1, 5), List.tabulate(5)(i => i * i)17.3 Vector (immutable, effectively O(1) indexed access & append)
Default choice for indexed sequences.
val v = Vector(1, 2, 3)
v(1), v.updated(1, 20), v :+ 4, 0 +: v17.4 Set & Map
val s = Set(1, 2, 3)
s + 4, s - 1, s.contains(2), s(2)
s ++ Set(5), s & Set(2, 3), s | Set(9), s diff Set(1)
val m = Map("a" -> 1, "b" -> 2)
m("a") // 1 (throws NoSuchElementException if missing)
m.get("z") // None
m.getOrElse("z", 0)
m + ("c" -> 3), m - "a", m ++ Map("d" -> 4)
m.updated("a", 10)
m.updatedWith("a")(_.map(_ + 1))
m.keys, m.values, m.toList
m.map((k, v) => k -> v * 2)
m.view.mapValues(_ * 2).toMap
m.filter((k, v) => v > 1)
m.withDefaultValue(0)("missing") // 017.5 Arrays (mutable, JVM arrays)
val arr = Array(1, 2, 3)
arr(0) = 10
Array.ofDim[Int](3, 3)
arr.sorted, arr.toList, arr.mkString(", ")17.6 Mutable collections
import scala.collection.mutable
val buf = mutable.ArrayBuffer(1, 2, 3)
buf += 4; buf ++= List(5, 6); buf -= 1; buf.insert(0, 0); buf.remove(0)
val counts = mutable.Map.empty[String, Int].withDefaultValue(0)
for w <- "a b a".split(" ") do counts(w) += 1
val pq = mutable.PriorityQueue(3, 1, 2)
pq.dequeue() // 317.7 Common operations (work on all collections)
val nums = List(5, 3, 8, 1, 9, 2)
nums.map(_ * 2)
nums.filter(_ > 3), nums.filterNot(_ > 3)
nums.flatMap(n => List(n, n))
nums.foldLeft(0)(_ + _), nums.foldRight(0)(_ + _)
nums.reduce(_ max _), nums.reduceOption(_ + _)
nums.sum, nums.product, nums.min, nums.max, nums.maxOption
nums.sorted, nums.sortBy(-_), nums.sortWith(_ > _)
nums.reverse, nums.distinct
nums.take(2), nums.drop(2), nums.takeWhile(_ > 2), nums.dropWhile(_ > 2)
nums.takeRight(2), nums.slice(1, 3), nums.splitAt(2)
nums.find(_ > 5), nums.exists(_ > 8), nums.forall(_ > 0), nums.count(_ % 2 == 0)
nums.indexOf(8), nums.indexWhere(_ > 5), nums.contains(3)
nums.partition(_ % 2 == 0) // (List(8, 2), List(5, 3, 1, 9))
nums.groupBy(_ % 3) // Map[Int, List[Int]]
nums.groupMapReduce(_ % 2)(identity)(_ + _)
nums.zip(nums.tail), nums.zipWithIndex, nums.unzip
nums.grouped(2).toList, nums.sliding(3).toList
nums.scanLeft(0)(_ + _)
nums.collect { case n if n > 4 => n * 10 }
nums.mkString("[", ", ", "]")
nums.headOption, nums.lastOption
nums.span(_ > 2), nums.tapEach(println)
nums.toSet, nums.toVector, nums.toArray, nums.iterator
List(List(1, 2), List(3)).flatten
List("a" -> 1, "b" -> 2).toMap
nums.dis
…17.8 Ranges
1 to 10, 1 until 10, 1 to 10 by 2, 10 to 1 by -1, 'a' to 'e'
BigDecimal(0) to BigDecimal(1) by BigDecimal("0.1") // Double ranges were removed in 2.13; use BigDecimal17.9 Views & laziness
Views apply transformations lazily without intermediate collections.
(1 to 1_000_000).view.map(_ * 2).filter(_ % 3 == 0).take(5).toList17.10 LazyList (lazy, memoized, possibly infinite)
val naturals: LazyList[Int] = LazyList.from(0)
val fibs: LazyList[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map(_ + _)
fibs.take(10).toList
LazyList.iterate(1)(_ * 2).takeWhile(_ < 1000).toList17.11 Iterators
Single-pass; cheap for streaming over data.
val it = Iterator(1, 2, 3)
while it.hasNext do println(it.next())
Iterator.continually(readLine()).takeWhile(_ != "quit")17.12 Performance characteristics
C = constant, eC = effectively constant, aC = amortized constant, L = linear.
17.13 Converting to/from Java collections
import scala.jdk.CollectionConverters.*
val jlist: java.util.List[Int] = List(1, 2).asJava
val slist: List[Int] = jlist.asScala.toList