In the previous section, we saw how to create the List
and Set
structures in Scala in an immutable way. Now we will learn to work with the List
and Set
structures in a mutable way, and also with other collections such as sequences, tuples, and Maps. Let's take a look at the Scala collections hierarchy tree, as shown in the following diagram:
Now let's take a look at the Scala Seq class hierarchy. As you can see, Seq is traversable as well.
Scala collections extend from traversable, which is the main trait of all collection's descends. List
structures, for instance, extend from Seq class hierarchy, which means sequence - List
is a kind of sequence. All these trees are immutable or mutable depending on the Scala package you end up using.
Let's see how to perform basic mutable operations with List
structures in Scala. In order to have filter and removal operations, we need use a Buffer
sequence as follows:
$ scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77). Type in expressions for evaluation. Or try :help. scala> var ms = scala.collection.mutable.ListBuffer(1,2,3) ms: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3) scala> ms += 4 res0: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4) scala> ms += 5 res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5) scala> ms += 6 res2: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6) scala> ms(1) res3: Int = 2 scala> ms(5) res4: Int = 6 scala> ms -= 5 res5: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 6) scala> ms -= 6 res6: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4) scala>
Let's see the next set of code.
We will see how to create, remove, and get an item from a mutable list in Scala REPL as follows:
$ scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77). Type in expressions for evaluation. Or try :help. scala> var names = scala.collection.mutable.SortedSet[String]("Diego", "Poletto", "Jackson") names: scala.collection.mutable.SortedSet[String] = TreeSet(Diego, Jackson, Poletto) scala> names += "Sam" res2: scala.collection.mutable.SortedSet[String] = TreeSet(Diego, Jackson, Poletto, Sam) scala> names("Diego") res4: Boolean = true scala> names -= "Jackson" res5: scala.collection.mutable.SortedSet[String] = TreeSet(Diego, Poletto, Sam) scala>
Have you ever wanted to return multiple values in a method? Well, in Java you have to create a class, but in Scala, there is a more convenient way to perform this task, and you won't need to create new classes each time. Tuples allow you to return or simply hold multiple values in methods without having to create a specific type.
We will see Scala tuples as follows:
$ scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77). Type in expressions for evaluation. Or try :help. scala> val config = ("localhost", 8080) config: (String, Int) = (localhost,8080) scala> config._1 res0: String = localhost scala> config._2 res1: Int = 8080 scala>
Scala has special methods called _1
and _2
which you can use to retrieve a tuple's values. The only thing you have to keep in mind is the fact that values are kept in the order of insertion in the tuple.
Scala has a very practical and useful collection library. A Map, for instance, is a key/value pair that can be retrieved based on the key, which is unique. However, Map values do not need to be unique. Like other Scala collections, you have mutable and immutable Map collections. Keep in mind that Scala favors immutable collections over mutable ones.
We will see Scala immutable Map in Scala REPL as follows:
$ scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77). Type in expressions for evaluation. Or try :help. scala> val numbers = Map("one" -> 1, | "two" -> 2, | "three" -> 3, | "four" -> 4, | "five" -> 5, | "six" -> 6, | "seven" -> 7, | "eight" -> 8, | "nine" -> 9, | "ten" -> 10) numbers: scala.collection.immutable.Map[String,Int] = Map(four -> 4, three -> 3, two -> 2, six -> 6, seven -> 7, ten -> 10, five -> 5, nine -> 9, one -> 1, eight -> 8) scala> scala> numbers.keys res0: Iterable[String] = Set(four, three, two, six, seven, ten, five, nine, one, eight) scala> scala> numbers.values res1: Iterable[Int] = MapLike(4, 3, 2, 6, 7, 10, 5, 9, 1, 8) scala> scala> numbers("one") res2: Int = 1 scala>
As you can see, Scala uses scala.collection.immutable.Map
when you create a Map using Map()
. Both keys and values are iterable, and you can have access to all the keys with the keys
method or to all the values using the values
method.
We will see Scala mutable Map in Scala REPL as follows:
$ scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77). Type in expressions for evaluation. Or try :help. scala> val map = scala.collection.mutable.HashMap.empty[Int,String] map: scala.collection.mutable.HashMap[Int,String] = Map() scala> map += (1 -> "one") res0: map.type = Map(1 -> one) scala> map += (2 -> "two") res1: map.type = Map(2 -> two, 1 -> one) scala> map += (3 -> "three") res2: map.type = Map(2 -> two, 1 -> one, 3 -> three) scala> map += (4 -> "mutable") res3: map.type = Map(2 -> two, 4 -> mutable, 1 -> one, 3 -> three) scala>
If you are dealing with mutable state, you have to be explicit and this is great in Scala, because it increases developers' awareness and avoids mutable shared state by default. So, in order to have a mutable Map, we need to explicitly create the Map with scala.collection.mutable.HashMap
.