Scala Collections

The API package scala.collection contains two sub-packages:

It also contains the declarations:

·       There are three types of collections: sequences, sets, and maps.

·       All three types are iterable (explained below).

·       Use sequences to represent ordered collections with non-unique members. (E.g., a schedule of recurring events.)

·       Use sets to represent unordered collections with unique members. (E.g., members of an organization.)

·       Use maps to represent indexed collections. (E.g., a phone book.)

·       Scala does not provide multisets (unordered collections with non-unique members.) Multi-sets need to be implemented by programmers.

scala.collection.immutable

·       We can't modify immutable collections. Adding or removing an element creates a new collection identical to the original collection, but with the element added or removed. Here are some examples of immutable collections:

o   Calendars: days of the week, hours of the day, etc.

o   Closed groups: The Greek gods, the 50 US states, etc.

o   Charts, timetables, menus, etc.

scala.collection.mutable

·       Use mutable collections when elements need to be added and removed without changing the identity of the collection. Here are some examples of mutable collections:

o   Current employees

o   Test scores

o   Symbol tables

Examples

Creating collections

scala> val numSet = Set(1, 2, 3, 4, 5, 6, 3, 7, 8, 9)
numSet: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 9, 2, 7, 3, 8, 4)

scala> val numSeq = Seq(1, 2, 3, 4, 5, 6, 3, 7, 8, 9)
numSeq: Seq[Int] = List(1, 2, 3, 4, 5, 6, 3, 7, 8, 9)

scala> val numMap = Map("one"->1, "two"->2, "three"->3)
numMap: scala.collection.immutable.Map[String,Int] = Map(one -> 1, two -> 2, three -> 3)

scala> numMap.size
res48: Int = 3

scala> numSeq.size
res49: Int = 9

Accessing collections

Many objects in Scala can be called like functions. (This is how functions can be data in Scala). Collections too can be called as functions:

scala> numSet(3)
res19: Boolean = true

scala> numSeq(3)
res20: Int = 4

scala> numMap("two")
res21: Int = 2

Traversing Collections (Iteration)

There are a number of ways to traverse collections in Scala.

scala> numMap.foreach(println _)
(one,1)
(two,2)
(three,3)

scala> for(i <- numMap) println(i)
(one,1)
(two,2)
(three,3)

scala> var it = numSet.iterator
it: Iterator[Int] = non-empty iterator

scala> while(it.hasNext) { println(it.next) }
5
1
6
9
2
7
3
8
4

Map, Filter, and Reduce

Algorithms that process, test, or combine the elements of a collection are so common that Scala provides higher-order methods for this purpose.

These methods take a function as input. The function describes how to process, test, or combine a single element.

scala> val numSeq2 = numSeq.filter((x: Int)=>x%2 == 0)
numSeq2: Seq[Int] = List(2, 4, 6, 8)

scala> numSeq2
res38: Seq[Int] = List(2, 4, 6, 8)

scala> numSeq
res39: Seq[Int] = List(1, 2, 3, 4, 5, 6, 3, 7, 8, 9)

scala> val numSet2 = numSet.map((x: Int)=>x * x)
numSet2: scala.collection.immutable.Set[Int] = Set(25, 1, 9, 64, 49, 81, 16, 36, 4)

scala> numSet2
res43: scala.collection.immutable.Set[Int] = Set(25, 1, 9, 64, 49, 81, 16, 36, 4)

scala> numSet
res44: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 9, 2, 7, 3, 8, 4)

scala> numSet.reduce((x: Int, y: Int)=> x + y)
res45: Int = 45

Adding and Removing Elements

scala> val names = collection.mutable.Set("James")
names: scala.collection.mutable.Set[String] = Set(James)

scala> names += "Hazel"
res61: names.type = Set(James, Hazel)

scala> names += "Soupie"
res62: names.type = Set(James, Soupie, Hazel)

scala> names += "James"
res63: names.type = Set(James, Soupie, Hazel)

scala> names -= "James"
res64: names.type = Set(Soupie, Hazel)

scala> val nums = collection.mutable.Buffer(0, 1)
nums: scala.collection.mutable.Buffer[Int] = ArrayBuffer(0, 1)

scala> nums += 2
res65: nums.type = ArrayBuffer(0, 1, 2)

scala> nums += 0
res66: nums.type = ArrayBuffer(0, 1, 2, 0)

scala> nums -= 0
res67: nums.type = ArrayBuffer(1, 2, 0)

scala> val scores = collection.mutable.Map[String, Int]()
scores: scala.collection.mutable.Map[String,Int] = Map()

scala> scores += "Carl"->100
res68: scores.type = Map(Carl -> 100)

scala> scores += "Wendy"-> 88
res69: scores.type = Map(Carl -> 100, Wendy -> 88)

scala> scores("Wendy") = 89

scala> scores
res73: scala.collection.mutable.Map[String,Int] = Map(Carl -> 100, Wendy -> 89)

References

·       http://docs.scala-lang.org/overviews/collections/overview.html

·       https://www.scala-lang.org/api/current/scala/collection/index.html