A Map is an Iterable consisting of pairs of keys and values (also named mappings or associations). Scala's Predef class offers an implicit conversion that lets you write key -> value as an alternate syntax for the pair (key, value). For instance Map("x" -> 24, "y" -> 25, "z" -> 26) means exactly the same as Map(("x", 24), ("y", 25), ("z", 26)), but reads better.

The fundamental operations on maps are similar to those on sets. They are summarized in the following table and fall into the following categories:

  • Lookup operations apply, get, getOrElse, contains, and isDefinedAt. These turn maps into partial functions from keys to values. 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.
  • Additions and updates +, ++, updated, which let you add new bindings to a map or change existing bindings.
  • Removals -, --, which remove bindings from a map.
  • Subcollection producers keys, keySet, keysIterator, values, valuesIterator, which return a map's keys and values separately in various forms.
  • Transformations filterKeys and mapValues, which produce a new map by filtering and transforming bindings of an existing map.

Maps can be created easily:

val myMap =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
myMap.size should be(res0)

Maps do not contain multiple identical pairs:

val myMap = Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "MI" -> "Michigan")
myMap.size should be(res0)

Maps can be added to easily:

val myMap = Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "MI" -> "Michigan")
val aNewMap = myMap + ("IL" -> "Illinois")
aNewMap.contains("IL") should be(res0)

Map values can be iterated:

val myMap = Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "MI" -> "Michigan")

val mapValues = myMap.values
mapValues.size should be(res0)
mapValues.head should be(res1) //Failed presumption: The order in maps is not guaranteed

val lastElement = mapValues.last
lastElement should be(res2)

Maps may be accessed:

val myMap =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
myMap("MI") should be(res0)
myMap("IA") should be(res1)

Maps insertion with duplicate key updates previous entry with subsequent value:

val myMap = Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "MI" -> "Meechigan")
val mapValues = myMap.values
mapValues.size should be(res0)
myMap("MI") should be(res1)

Map keys may be of mixed type:

val myMap = Map("Ann Arbor" -> "MI", 49931 -> "MI")
myMap("Ann Arbor") should be(res0)
myMap(49931) should be(res1)

If a nonexistent map key is requested using myMap(missingKey), a NoSuchElementException will be thrown. Default values may be provided using either getOrElse or withDefaultValue for the entire map:

val myMap =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
intercept[NoSuchElementException] {
  myMap("TX")
}
myMap.getOrElse("TX", "missing data") should be(res0)

val myMap2 =
  Map(
    "MI" -> "Michigan",
    "OH" -> "Ohio",
    "WI" -> "Wisconsin",
    "IA" -> "Iowa") withDefaultValue "missing data"
myMap2("TX") should be(res1)

Map elements can be removed easily:

val myMap =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
val aNewMap = myMap - "MI"
aNewMap.contains("MI") should be(res0)
myMap.contains("MI") should be(res1)

Map elements can be removed in multiple:

val myMap =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
val aNewMap = myMap -- List("MI", "OH")

aNewMap.contains("MI") should be(res0)
myMap.contains("MI") should be(res1)

aNewMap.contains("WI") should be(res2)
aNewMap.size should be(res3)
myMap.size should be(res4)

Attempted removal of nonexistent elements from a map is handled gracefully:

val myMap =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
val aNewMap = myMap - "MN"

aNewMap.equals(myMap) should be(res0)

Map equivalency is independent of order:

val myMap1 =
  Map("MI" -> "Michigan", "OH" -> "Ohio", "WI" -> "Wisconsin", "IA" -> "Iowa")
val myMap2 =
  Map("WI" -> "Wisconsin", "MI" -> "Michigan", "IA" -> "Iowa", "OH" -> "Ohio")

myMap1.equals(myMap2) should be(res0)