Maps

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 "mgetkey" 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.

TransformationsfilterKeys and mapValues, which
produce a new map by filtering and transforming bindings of an existing map.

Operations in class Map

What it is

What it does

Lookups:

msgetk

The value associated with key k in map ms as an option, None if not found.

ms(k)

(or, written out, msapplyk)
The value associated with key k in map ms, or exception if not found.

msgetOrElse(k,d)

The value associated with key k in map ms, or the default value d if not found.

mscontainsk

Tests whether ms contains a mapping for key k.

msisDefinedAtk

Same as contains.

Additions and Updates:

ms+(k->v)

The map containing all mappings of ms as well as the mapping k->v from key k to value v.

ms+(k->v,l->w)

The map containing all mappings of ms as well as the given key/value pairs.

ms++kvs

The map containing all mappings of ms as well as all key/value pairs of kvs.

msupdated(k,v)

Same as ms+(k->v).

Removals:

ms-k

The map containing all mappings of ms except for any mapping of key k.

ms-(k,l,m)

The map containing all mappings of ms except for any mapping with the given keys.

ms--ks

The map containing all mappings of ms except for any mapping with a key in ks.

Subcollections:

ms.keys

An iterable containing each key in ms.

ms.keySet

A set containing each key in ms.

ms.keysIterator

An iterator yielding each key in ms.

ms.values

An iterable containing each value associated with a key in ms.

ms.valuesIterator

An iterator yielding each value associated
with a key in ms.

Transformation:

msfilterKeysp

A map view containing only those mappings in ms where the key
satisfies predicate p.

msmapValuesf

A map view resulting from applying function f to each value
associated with a key in ms.

Mutable maps support in addition the operations
summarized in the following table.

Operations in class mutable.Map

What it is

What it does

Additions and Updates:

ms(k)=v

(Or, written out, ms.update(x,v)). Adds mapping from key k to value v to map ms as a side effect, overwriting
any previous mapping of k.

ms+=(k->v)

Adds mapping from key k to value v to map ms as a side effect and returns ms itself.

ms+=(k->v,l->w)

Adds the given mappings to ms as a side effect and returns ms itself.

ms++=kvs

Adds all mappings in kvs to ms as a side effect and returns ms itself.

msput(k,v)

Adds mapping from key k to value v to ms and returns any value
previously associated with k as an option.

msgetOrElseUpdate(k,d)

If key k is defined in map ms, return its associated value. Otherwise,
update ms with the mapping k->d and return d.

Removals:

ms-=k

Removes mapping with key k from ms as a side effect and returns ms itself.

ms-=(k,l,m)

Removes mappings with the given keys from ms as a side effect and returns ms itself.

ms--=ks

Removes all keys in ks from ms as a side effect and returns ms itself.

msremovek

Removes any mapping with key k from ms and returns any value
previously associated with k as an option.

msretainp

Keeps only those mappings in ms that have a key satisfying predicate p.

ms.clear()

Removes all mappings from ms.

Transformation:

mstransformf

Transforms all associated values in map ms with function f.

Cloning:

ms.clone

Returns a new mutable map with the same mappings as ms.

The addition and removal operations for maps mirror those for sets.
As is the for sets, mutable maps also support the non-destructive
addition operations +, -, and updated, but they are used less
frequently because they involve a copying of the mutable map.
Instead, a mutable map is m usually updated "in place", using
the two variants m(key)=value or m+=(key->value). There are is also the variant mput(key,value), which
returns an Option value that contains the value
previously associated with key, or None if the key did not
exist in the map before.

The getOrElseUpdate is useful for accessing maps that act as
caches. Say you have an expensive computation triggered by invoking
a function f:

scala> def f(x: String) = {

println("taking my time."); sleep(100)

x.reverse }

f: (x: String)String

Assume further that f has no side-effects, so invoking it again
with the same argument will always yield the same result. In that case
you could save time by storing previously computed bindings of
argument and results of f in a map and only computing the result of
f if a result of an argument was not found there. One could say the map is a
cache for the computations of the function f.

val cache = collection.mutable.Map[String, String]()

cache: scala.collection.mutable.Map[String,String] = Map()

You can now create a more efficient caching version of the f
function:

scala> def cachedF(s: String) = cache.getOrElseUpdate(s, f(s))

cachedF: (s: String)String

scala> cachedF("abc")

taking my time.

res3: String = cba

scala> cachedF("abc")

res4: String = cba

Note that the second argument to getOrElseUpdate is "by-name", so the computation of f("abc") above is only performed if
getOrElseUpdate requires the value of its second argument, which is
precisely if its first argument is not found in the cache map.
You could also have implemented cachedF directly, using just basic
map operations, but it would take more code to do so: