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:
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 :
- keys : returns an iterable containing each key in the map.
- values: returns an iterable containing each value in the map.
- 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 :
- Programming in Scala, Third Edition, Martin Odersky
- https://www.tutorialspoint.com/scala/scala_maps.htm
- http://alvinalexander.com/scala/scala-maps-map-class-examples
Reblogged this on akashsethi24.
Reblogged this on Mahesh's Programming Blog.