Rearrange the following blocks so that they form a function that takes as input a list of words. It then goes through the words and uses a map to keep track of how many times it has seen each word. When it sees a word that it has seen before, it prints a message about how many times the word has been seen. All blocks will be used.
Section 3.3 The Map interface and HashMap class
As we mentioned earlier in the section, maps are used to hold key-value pairs. As such, in order to use a map we need to specify two classes: One for the keys, typically strings, and one for the values. Similar to the List/ArrayList situation, we have the interface
Map
, which prescribes what kinds of functions we have, and the class HashMap
, which provides an implementation of those functions.Let’s take a look at an example of a map that actually does something useful: Given a list of words, it counts how many times each word occurs. Then it prints those counts.
List<String> words = // ... A list of words here
Map<String, Integer> wordCounts = new HashMap<>();
for (String word : words) {
int currentCount = wordCounts.getOrDefault(word, 0);
wordCounts.put(word, currentCount + 1);
}
for (Map.Entry<String, Integer> entry : wordCounts.entrySet()) {
System.out.printf("%s: %d%n", entry.getKey(), entry.getValue());
}
There’s a lot to cover here, so let’s get started.
- Line 2 creates a new
Map
calledwordCounts
. By the angle bracket specification ofString, Integer
we learn that this map usesString
keys and storesInteger
values. - The map is initialized as an empty
HashMap
by calling that class’ constructor. -
In lines 3-5 we iterate over the list of words. We first use a convenient method that maps provide, called
getOrDefault
, which looks up the value for a provided key and if it is not found then it uses the provided default value, in our case0
. The end result is that thecurrentCount
variable will contain the number of times we have seen this word so far.Then in line 5 we increment that value by1
and store the result using the map methodput
.We could have done this loop in a few other ways, I encourage you to look at theMap
documentation for the various functions provided. - The next interesting part is lines 6-8. There we iterate over the map, then print the results. The first tricky bit is how to iterate. This is done by asking for the map’s
entrySet
, which is in effect a list of objects of classMap.Entry
. This is a very simple class that holds two fields,key
andvalue
. So for every key-value pair in our map, we will have one of these objects provided to us in the loop. - Lastly, we learn about a new method for printing formatted information, namely
System.out.printf
. It expects a format stringas the first argument, and then uses the subsequent arguments as value fillers. In this case we use1
docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Formatter.html
%s
for a string and%d
for an integer.
If you try this little bit of code with a list of words, you should be able to run it and see a nice output.