Scala Map

Reading Time: 6 minutes

Scala Map is a collection of Key-value pair. A map cannot have duplicate keys but different keys can have same values i.e keys are unique whereas values can be duplicate.

Maps in Scala are not language syntax. They are library abstractions that you can extend and adapt.

Scala provides mutable and immutable alternatives for maps. Class hierarchy for scala maps is shown below:

Screenshot from 2017-04-28 18-34-09 

Image is taken from Programming in Scala by Martin Odersky

There’s a base Map trait in package scala.collection, and two subtraits – a mutable Map in scala.collection.mutable and an immutable one in scala.collection.immutable . By default Scala Map is immutable but if you want to use mutable one then you need to import mutable Map by using statement : import scala.collection.mutable

Creating and initializing a map :

val tasks = Map(1 -> “Book movie tickets”,2 -> “Go shopping”)

The Scala compiler transforms a binary operation expression like 1 -> “Book movie ticket” into (1).->(“Book movie ticket”) . Thus, when you say 1 -> “Book movie ticket” ,you are actually calling a method named -> on an integer with the value 1, passing in a string with the value “Book movie ticket”. This -> method, which you can invoke on any object in a Scala program, returns a two-element tuple containing the key and value.

Maps are Iterables of pairs of keys and values (also named mappings or associations). Scala’s Predef object offers an implicit conversion that lets you write key -> value as an alternate syntax for the pair (key, value). Therefore, Map(1 -> “Book movie ticket” , 2 ->”Go shopping”) means exactly same as Map((1,”Book movie ticket”),(2,”Go shopping”))

Creating a mutable map :

import scala.collection.mutable

val tasks = mutable.Map[Int,String]()

tasks += (1 -> “Book a movie ticket”)

tasks += (2 -> “Go shopping”)

Basic operations on map :

  1. keys : returns an iterable containing each key in the map.
  2. values:  returns an iterable containing each value in the map.
  3. isEmpty: returns true if the map is empty otherwise false.

Example:

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

subjects.keys

subjects.values

subjects.isEmpty

will give result :

res0: Iterable[Int] = Set(1, 2, 3)

res1: Iterable[String] = MapLike.DefaultValuesIterable(DS, C++, Java)

res2: Boolean = false

Map operations fall into the following categories :

1. Lookups – These operations turn maps into partial functions from keys to values. Lookups operations include apply , get , getOrElse , contains , and isDefinedAt. The fundamental lookup method for a map is:

def get(key): Option[Value]

The operation “m get key ” tests whether the map contains an association for the given key . If so, it returns the associated value in a Some . If no key is defined in the map, get returns None . Maps also define an apply method that returns the value associated with a given key directly, without wrapping it in an Option . If the key is not  defined in the map, an exception is raised.

Example:

Let’s say we have a Map :     val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

  • Get operation : will return the value associated with key in map subjects as an option, or None if not found

subjects get(1)

will result in:

res0: Option[String] = Some(DS)

  • apply operation :The value associated key in map subjects , or throw an exception if not found

subjects(1)

will result in:

res1: String = DS

  • getOrElse : The value associated key  in map  , or the default value if not found.

subjects getOrElse(4,”DCN”)

will result in:

res2: String = DCN

2. Additions and updates  – These operations let you add new bindings to a map or change existing bindings. + , ++ , and updated are included in this categories.

Examples:

  • + operation :  Used to add single element

subjects + (4 ->”Operating system”)

will result in :

res0: scala.collection.immutable.Map[Int,String] = Map(1 -> DS, 2 -> C++, 3 -> Java, 4       -> Operating system)

  • ++ operation : Used to add multiple Maps

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

val newSubjects = Map(3 -> “Scala”, 4 -> “c#”)

val listOfSubjects = subjects ++ newSubjects

will result in :

listOfSubjects: scala.collection.immutable.Map[Int,String] = Map(1 -> DS, 2 -> C++,

3 -> Scala, 4 -> c#)

  • updated operation : To update the value of particular key.

subjects updated(1,”OS”)

will result in :

res0: scala.collection.immutable.Map[Int,String] = Map(1 -> OS, 2 -> C++, 3 -> Java)

3. Removals –  These operations remove bindings from a map. They include – and —

      Example :

  • operation: Use to remove one element from Map.

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

subjects – 1

will result in :

res0: scala.collection.immutable.Map[Int,String] = Map(2 -> C++, 3 -> Java)

4. Subcollection producers – They return a map’s keys and values separately in various forms. They include keys , keySet , keysIterator , valuesIterator , and values.

Example :

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

  • Keys : returns an iterable containing each key in the map

subjects.keys

will result in :

res0: Iterable[Int] = Set(1, 2, 3)

  • keySet : returns a set containing each key in the map

subjects.keySet

will result in :

res1: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

  •   keysIterator: returns  an  iterator over all keys in the map

subjects.keysIterator.toSet

will result in :

res2: Iterator[Int] = non-empty iterator

  • valuesIterator:  returns an iterator over all values that are associated with some key in the map

subjects.valuessIterator.toSet

will result in :

res3: Iterator[String] = non-empty iterator

5. Transformations – They produce a new map by filtering and transforming bindings of an existing map.They include  filterKeys and mapValues

Example:

  • filterKeys : Filters the map by retaining only keys satisfying a predicate.

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

subjects.filterKeys(x => x%2 == 0)

will result in :

res0: scala.collection.immutable.Map[Int,String] = Map(2 -> C++)

  • mapValues : Transforms the map by applying a function to every retrieved value.

val values = Map( “a” -> 1, “b” -> 2 )

values.mapValues(_ * 2)

will result in:

res1: scala.collection.immutable.Map[String,Int] = Map(a -> 2, b -> 4)

Concatenating two maps:

To concatenate two or more maps we use  ++ operator or Map.++() method. While doing so duplicate keys are removed and only the last value will be stored in map for example:

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

val newSubjects = Map(3 -> “Scala”, 4 -> “c#”)

subjects ++ newSubjects

This will result in :

res0: scala.collection.immutable.Map[Int,String] = Map(1 -> DS, 2 -> C++, 3 -> Scala, 4 -> c#)

Duplicate key 3 having value java is replaced by new value of 3.

Iterating over Scala maps:

You can iterate over Map using several different techniques. Some are :

  • For loop :

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

for ((key, value) <- subjects){

println(“key is : ” + key + ” its vaue is : ” + value)
}
  • Foreach loop:

val subjects = Map(1 -> “DS”,2 -> “C++”,3 -> “Java”)

subjects foreach{case (key,value) =>

println(“key is : ” + key +” its vaue is : ” + value)}

Understanding mutable variables with immutable collections

Mixing a mutable variable (var) with an immutable collection causes surprising behavior.

While creating an immutable Map as a var, it appears you can somehow add new elements to it:

var subjects = Map(1 -> “DS”)

subjects += (2 -> “C++”)

subjects += (3 -> “Java”)

It looks like you’re mutating an immutable collection, what’s really happening is that the subjects variable points to a new collection each time you use the += method.

The subjects variable is mutable — like a non-final field in Java — so it’s actually being reassigned to a new collection during each step.

The end result is as follows:

var subjects = Map(1 -> “DS”)

subjects += (1 -> “DS”,2 -> “C++”)

subjects += (1 -> “DS”,2 -> “C++”,3 -> “Java”)

When you first start working with Scala, the behavior of a mutable variable with an immutable collection can be surprising. To be clear about variables and values:

  • A mutable variable (var) can be reassigned to point at new data.
  • An immutable variable (val) is like a final variable in Java; it can never be reassigned.

I hope this blog is helpful for you. Comments and suggestions are welcomed.

References :

  1.  Programming in Scala, Third Edition, Martin Odersky
  2. https://www.tutorialspoint.com/scala/scala_maps.htm
  3. http://alvinalexander.com/scala/scala-maps-map-class-examples

KNOLDUS-advt-sticker

Written by 

I am a Software Consultant and has experience of more than 1.5 years. I like to study and write about latest technologies.

3 thoughts on “Scala Map7 min read

Comments are closed.