What is it?
A map is a construct that allows us to pair keys and values. Maps are sometimes referred to as tables or dictionaries.
Let's say that I have the following student information:
Student ID | Name |
---|---|
23A52 | Harvey Dent |
68Z29 | Jessica Jones |
57W85 | J Jonah Jameson |
Each student will have a unique ID, but multiple students could have the same name.
How do I build it?
Each student ID (key) corresponds to a student name (value). Each of these key/value pairs is known as a map entry. In Java, we can create a Map
to hold these entries.
key ↓↓↓ Student ID |
value ↓↓↓ Name |
---|---|
23A52 | Harvey Dent |
68Z29 | Jessica Jones |
57W85 | J Jonah Jameson |
Map
is a parameterized type, so we declare it thus:
const students = new Map();
To add students, we use set(key, value)
:
students.set("23A52", "Harvey Dent")
students.set("68Z29", "Jessica Jones")
students.set("57W85", "J Jonah Jameson")
Let's look at what we've got:
console.log(`The students are ${students}`); // prints "The students are [object Map]"
[object Map]
is the default response from the toString()
method. The good news is that we do have a Map
. We'll take a look at how to get a more informative response from toString
later.
What is it Good For?
We know that we could use an array or an object to hold collections of things, so why Map
?
Imagine we wanted to look up students by name from our example student information.
First, we'd need to create an object to hold student ID and name:
class Student {
constructor(id, name) {
this.id = id
this.name = name
}
}
Assuming we have populated a collection of Student
objects, to find a student by ID, we'd do something like this:
for(let current of students) {
if("23A52" === current.id)) {
console.log("Found the student!");
console.log("The student's name name is " + current.name);
break;
}
}
Maps make this easier. Also, what if there were 20,000 students and the one we were looking for was 19,998th in our list? Maps also perform better for doing lookups like this.
Finding our Student
Map
defines a method called get
. Given a key, the get
method will return its value.
Assuming we have populated a Map
named students
whose keys are IDs (String
s) and whose values are student names (String
s), finding a student by ID with a Map
is simple:
const studentName = students.get("23A52");
console.log("Found the student!");
console.log("The student's name name is " + studentName);
Map
keys can not be duplicated and we don't care about their order, so we use a Set
to represent them.
Map
values can be duplicated, but their order isn't significant. These are represented by an Array
.
Keys, Values, and Entries
To look at a Map
s keys, we call its keys
method:
const studentIds = students.keys();
console.log("The student IDs are " + studentIds);
To look at a Map
's values, we call its values
(Surprise!) method:
const studentNames = students.values();
console.log("The student names are " + studentNames);
If we want to iterate over all (or many) of the entries in a map, looking at both key and value, it is intuitive to do something like this:
for(let id of students.keySet()) {
console.log("This student's name is " + students.get(id));
}
The problem with this approach is that it will result in poor performance. (This is a common interview question.) This is because looking up the value for a key requires effort, and this code would look up the value for every key.
If we want to iterate over all keys and values, we do something like this instead:
for(let entry of students.entries()) {
console.log("The student's id is " + entry[0]);
console.log("The student's name is " + entry[1]);
}
Other Useful Map
Methods
method | what does it do? |
---|---|
delete(key) | removes the entry associated with key |
has(key) | returns true if this map contains the key |
size() | returns the number of entries in the map |
clear() | removes all entries from the map |
WeakMap
JS also has the concept of WeakMap
s. These operate almost the exact same way as our standard Map
s. The biggest difference is that these Maps can only have Object
s as keys NO PRIMITIVES. There are also fewer methods available:
method | what it does |
---|---|
delete(key) | removes entry |
has(key) | returns boolean value for existence of key |
get(key) | returns value associated with key |
set(key, value) | sets given value to assigned key (must be object) |