A Map Stores Key-Value Pairs
A HashMap (from java.util) stores associations: each key maps to one value, and you look values up by their key in roughly constant time. Think of a dictionary - the word is the key, the definition is the value.
The two type parameters are <KeyType, ValueType>. Here keys are String and values are Integer. As with ArrayList, you typically type the variable as the Map interface and construct a HashMap.
put, get, and Overwriting
Two things to internalize:
- A key is unique.
putwith an existing key replaces its value and returns the old one. geton a missing key returnsnull, not an error. Auto-unboxing thatnullinto anintthrows aNullPointerException, which is a common source of bugs.
getOrDefault Avoids the Null Trap
Rather than checking for null every time, ask for a fallback:
This is the cleanest way to handle "maybe present" lookups, and it leads directly to the most famous HashMap pattern.
Counting Occurrences
Counting how many times each item appears is the textbook HashMap job:
The pattern map.put(key, map.getOrDefault(key, 0) + 1) reads as "take the current count (or zero), add one, store it back". A tidier equivalent is counts.merge(word, 1, Integer::sum).
Checking and Removing
putIfAbsent(key, value) only writes when the key is missing - useful for lazy initialization.
Looping Over a HashMap
The most common loop walks entrySet(), giving you each key and value together:
If you only need the keys or only the values:
You can also use forEach with a lambda: ages.forEach((name, age) -> System.out.println(name + ": " + age));.
HashMap Does Not Keep Order
A HashMap makes no promise about iteration order - it is whatever the hashing produces, and it can change between runs. If you need a predictable order:
LinkedHashMappreserves insertion order.TreeMapkeeps keys sorted by natural ordering (or aComparatoryou supply).
All three implement the Map interface, so switching is a one-line change to the constructor.
Keys Must Be Hashable
HashMap finds entries by hashing the key, so a key's hashCode() and equals() must agree. Built-in types like String and Integer already do this correctly. If you use your own class as a key, override both equals and hashCode - or two objects that are "equal" in meaning will land in different buckets and your lookups will mysteriously fail.
Next: HashSet
A HashMap answers "what value is stored under this key?". When you only care whether something is present at all - a set of unique values, with no associated data - the tool is HashSet, coming up next.
Frequently Asked Questions
How do you create a HashMap in Java?
Declare it with two type parameters - the key type and the value type - and call the constructor: Map<String, Integer> ages = new HashMap<>();. Then add entries with ages.put("Ada", 36); and read them with ages.get("Ada");. Import java.util.HashMap and java.util.Map.
How do you loop through a HashMap in Java?
Iterate map.entrySet() with a for-each loop to get each key and value together: for (Map.Entry<String, Integer> e : map.entrySet()) { ... }, reading e.getKey() and e.getValue(). You can also loop map.keySet() for just the keys or map.values() for just the values. Note that a HashMap does not keep insertion order.
What is the difference between get and getOrDefault?
get(key) returns the value for a key, or null if the key is absent - which can lead to a NullPointerException if you use the result directly. getOrDefault(key, fallback) returns the value if present, otherwise the fallback you pass, so you avoid the null check. It is especially handy for counting: counts.put(c, counts.getOrDefault(c, 0) + 1).