HashMap
A map stores key-value pairs: you look a value up by its key, like a word in a dictionary.
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> stock = new HashMap<>();
stock.put("apples", 40);
stock.put("bananas", 25);
stock.put("cherries", 0);
System.out.println(stock.get("apples")); // 40
System.out.println(stock.get("mangoes")); // null: no such key
System.out.println(stock.containsKey("bananas")); // true
stock.put("apples", 35); // the same key replaces the value
stock.remove("cherries");
System.out.println(stock.size()); // 2
System.out.println(stock.getOrDefault("mangoes", 0)); // 0
}
}- Keys are unique: putting an existing key replaces its value.
getreturnsnullfor a missing key, whilegetOrDefaultreturns the fallback you give it.- Both types in
Map<String, Integer>must be objects, so numbers use wrapper types likeInteger.
Looping over a map
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> lessons = new HashMap<>();
lessons.put("Python", 64);
lessons.put("SQL", 23);
lessons.put("HTML", 17);
for (Map.Entry<String, Integer> e : lessons.entrySet()) {
System.out.println(e.getKey() + " has " + e.getValue() + " lessons");
}
System.out.println(lessons.keySet());
System.out.println(lessons.values());
}
}A HashMap keeps no particular order, so the entries may come out in a different order from the one you added them in.
Counting with a map
Java
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
String text = "the cat and the hat and the bat";
Map<String, Integer> counts = new TreeMap<>();
for (String word : text.split(" ")) {
counts.put(word, counts.getOrDefault(word, 0) + 1);
}
System.out.println(counts); // {and=2, bat=1, cat=1, hat=1, the=3}
Map<Character, Integer> letters = new TreeMap<>();
for (char ch : "banana".toCharArray()) {
letters.merge(ch, 1, Integer::sum); // start at 1, or add 1
}
System.out.println(letters); // {a=3, b=1, n=2}
}
}getOrDefault(word, 0) + 1 is the classic counting pattern. merge does the same in one call: if the key is new it stores 1, and otherwise it combines the old value with 1 using Integer::sum.
Which map?
| Class | Order of keys | Speed |
|---|---|---|
HashMap | no particular order | fastest |
LinkedHashMap | the order they were inserted | nearly as fast |
TreeMap | sorted by key | a little slower |
Lists as values
Java
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
String[][] enrolments = { {"Asha", "Python"}, {"Leo", "SQL"}, {"Mei", "Python"}, {"Raj", "SQL"}, {"Zoe", "Java"} };
Map<String, List<String>> byCourse = new LinkedHashMap<>();
for (String[] row : enrolments) {
byCourse.computeIfAbsent(row[1], k -> new ArrayList<>()).add(row[0]);
}
System.out.println(byCourse); // {Python=[Asha, Mei], SQL=[Leo, Raj], Java=[Zoe]}
}
}computeIfAbsent creates the list the first time a course appears, and returns the existing list every time after, ready for add.
Finished this lesson?Mark it complete to earn +20 XP and move your progress on.