Maps, Options, and Tuples
Hash tables—or, more generally, maps—are among the most versatile data structures. Scala makes it particularly easy to use them.
Topics in This Chapter A1
4.1 Constructing a Map
4.2 Accessing Map Values
4.3 Updating Map Values
4.4 Iterating over Maps
4.5 Linked and Sorted Maps
4.6 Interoperating with Java
4.7 The Option Type
4.8 Tuples
4.9 Zipping
Exercises
A classic programmer’s saying is, “If you can only have one data structure, make it a hash table.” Hash tables—or, more generally, maps—are among the most versatile data structures. As you will see in this chapter, Scala makes it particularly easy to use them.
When looking up a key in a map, there may not be a matching value. An option is perfect for describing that situation. An option is used in Scala whenever a value may be present or absent.
Maps are collections of key/value pairs. Scala has a general notion of tuples—aggregates of n objects, not necessarily of the same type. A pair is simply a tuple with n = 2. Tuples are useful whenever you need to aggregate two or more values together.
Highlights of the chapter are:
Scala has a pleasant syntax for creating, querying, and traversing maps.
You need to choose between mutable and immutable maps.
By default, you get a hash map, but you can also get a tree map.
You can easily convert between Scala and Java maps.
Use the Option type for values that may or may not be present—it is safer than using null.
Tuples are useful for aggregating values.
4.1 Constructing a Map
You can construct a map as
val scores = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)
This constructs an immutable Map[String, Int] whose contents can’t be changed. See the next section for mutable maps.
If you want to start out with a blank map, you have to supply type parameters:
val scores = scala.collection.mutable.Map[String, Int]()
In Scala, a map is a collection of pairs. A pair is simply a grouping of two values, not necessarily of the same type, such as ("Alice", 10).
The -> operator makes a pair. The value of
"Alice" -> 10
is
("Alice", 10)
You could have equally well defined the map as
Map(("Alice", 10), ("Bob", 3), ("Cindy", 8))
The -> operator is just a little easier on the eyes than the parentheses. It also supports the intuition that a map data structure is a kind of function that maps keys to values. The difference is that a function computes values, and a map just looks them up.