Java HashMap Tutorial with Examples: put, get, Iterate, Count, and Sort by Value
Almost every real program needs to look something up quickly: a student's grade by ID number, a product's price by its code, or how many times a word appears in a text. In Java, the go-to tool for this job is the HashMap. It stores data as key-value pairs and can find a value by its key almost instantly, no matter how many entries it holds.
In this tutorial, you will learn how to use HashMap in Java step by step: creating a map, adding and reading values, the different ways to loop through it, counting with merge(), grouping with computeIfAbsent(), sorting a HashMap by value, and using your own class as a key. Every example is a complete program that was compiled and run on Java 21, and the output shown is the real output.
What Is a HashMap?
A HashMap<K, V> is part of the Java Collections Framework (java.util). Think of it as a dictionary: each key is unique and points to exactly one value. A few important rules:
- Keys are unique. Putting a value with an existing key replaces the old value.
- Order is not guaranteed. A HashMap does not remember insertion order or sort its keys.
- One null key and many null values are allowed.
- It is fast.
get(),put()andremove()run in constant time on average. - It is not thread-safe. Use
ConcurrentHashMapwhen multiple threads write to the same map.
Requirements
- JDK 11 or newer (the examples were tested with JDK 21).
- Any editor or IDE: VS Code, IntelliJ IDEA, NetBeans or Eclipse.
Step 1: Basic HashMap Operations
Let's start with the methods you will use every day: put(), get(), getOrDefault(), containsKey(), containsValue(), remove() and size(). Create a file named HashMapBasics.java:
- import java.util.HashMap;
- import java.util.Map;
- public class HashMapBasics {
- // Create a HashMap: key = student name, value = score
- // put() adds a new entry or replaces the value of an existing key
- scores.put("Ana", 88);
- scores.put("Ben", 75);
- scores.put("Carla", 92);
- scores.put("Ben", 81); // replaces 75
- // get() returns the value, or null if the key is missing
- // getOrDefault() avoids null
- // containsKey() and containsValue()
- // remove() deletes by key and returns the old value
- }
- }
Run it with java HashMapBasics.java (Java 11 or newer can run a single source file directly). Output:
Map: {Carla=92, Ana=88, Ben=81}
Size: 3
Ana's score: 88
Dan's score: null
Dan's score (default): 0
Has Carla? true
Anyone with 100? false
Removed Ben (81), map is now: {Carla=92, Ana=88}
Notice three things in the output. First, putting "Ben" a second time replaced his score instead of adding a new entry. Second, get("Dan") returned null because the key does not exist; calling a method on that result would throw a NullPointerException, which is why getOrDefault() is safer. Third, the map printed the names in an order that is different from how we inserted them. That is normal for a HashMap.
We declared the variable as Map<String, Integer> instead of HashMap<String, Integer>. Coding to the interface is a good habit, because you can later switch to a TreeMap or LinkedHashMap by changing only one line.
Step 2: How to Iterate Over a HashMap
There are three common ways to loop through a HashMap. Use entrySet() when you need both the key and the value, keySet() or values() when you need only one side, and forEach() with a lambda for short, readable code. Save this as IterateHashMap.java:
- import java.util.HashMap;
- import java.util.Map;
- import java.util.TreeMap;
- public class IterateHashMap {
- prices.put("Coffee", 120.0);
- prices.put("Tea", 95.5);
- prices.put("Cake", 150.0);
- // 1. entrySet(): best when you need both key and value
- }
- // 2. keySet() and values()
- }
- double total = 0;
- for (double p : prices.values()) {
- total += p;
- }
- // 3. forEach() with a lambda (Java 8+)
- // HashMap does not keep any order. Use TreeMap for sorted keys.
- }
- }
Run it with java IterateHashMap.java (Java 11 or newer can run a single source file directly). Output:
-- entrySet -- Tea = 95.5 Cake = 150.0 Coffee = 120.0 -- keySet -- Tea Cake Coffee Total of all prices: 365.5 -- forEach -- Tea PHP 95.50 Cake PHP 150.00 Coffee PHP 120.00 -- sorted by key -- Cake -> 150.0 Coffee -> 120.0 Tea -> 95.5
If you need the keys in alphabetical order, copy the map into a TreeMap, as shown at the end of the program. If you need to keep the order in which items were added, use a LinkedHashMap instead.
Step 3: Counting, Grouping and Sorting by Value
Since Java 8, Map has methods that remove a lot of boilerplate code. The most useful are:
merge(key, value, function)– perfect for counters. If the key is new, it stores the value; otherwise it combines the old and new values.computeIfAbsent(key, function)– creates a value only when the key is missing. Great for grouping items into lists.putIfAbsent(key, value)– adds the entry only if the key does not exist yet.
This program counts words in a sentence, prints the top 3 words sorted by count, and groups words by their first letter. Save it as WordCounter.java:
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class WordCounter {
- // Count words with merge(): add 1, or start at 1 if the key is new
- }
- // Top 3 words, highest count first, then alphabetical
- counts.entrySet().stream()
- .limit(3)
- // Group words by their first letter with computeIfAbsent()
- byLetter.computeIfAbsent(word.charAt(0), k -> new ArrayList<>()).add(word);
- }
- byLetter.values().forEach(list -> list.sort(null));
- // putIfAbsent() only adds when the key is missing
- counts.putIfAbsent("cat", 0);
- counts.putIfAbsent("the", 100); // ignored, "the" already exists
- }
- }
Run it with java WordCounter.java (Java 11 or newer can run a single source file directly). Output:
the = 3 fox = 2 dog = 1 -- top 3 -- the: 3 fox: 2 brown: 1 Words starting with 'f': [fox] Words starting with 'd': [dog] cat = 0, the = 3
The line counts.merge(word, 1, Integer::sum) replaces the classic five-line "if the key exists, add one, else put one" pattern. To sort by value, we stream the entries and use Map.Entry.comparingByValue().reversed(), then break ties alphabetically with comparingByKey(). A HashMap itself can never be sorted, so sorting always produces a new list or stream.
Step 4: Using Your Own Class as a Key
You can use any object as a key, but there is one rule you must follow: override both equals() and hashCode(). HashMap uses hashCode() to find the right bucket and equals() to find the exact key inside it. If you forget them, two objects with the same data are treated as different keys, and get() returns null even though the entry is "there." Save this as Student.java:
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Objects;
- public class Student {
- this.id = id;
- this.name = name;
- }
- // Two students are equal when their IDs are equal
- @Override
- if (this == o) return true;
- if (!(o instanceof Student)) return false;
- return id.equals(((Student) o).id);
- }
- @Override
- public int hashCode() {
- return Objects.hash(id);
- }
- @Override
- return name + " (" + id + ")";
- }
- Map<Student, String> sections = new HashMap<>();
- sections.put(new Student("2026-001", "Ana Cruz"), "BSIT 2A");
- // A different object with the same ID finds the same entry
- Student lookup = new Student("2026-001", "Ana Cruz");
- }
- }
Run it with java Student.java (Java 11 or newer can run a single source file directly). Output:
Section of Ana Cruz (2026-001): BSIT 2A Entries: 1
Because both methods are based on the student ID, a brand-new Student object with the same ID finds the existing entry. Try deleting the two methods and running the program again: the lookup will print null. Also, avoid changing a key object's fields after you put it in a map, since its hash code would change and the entry would become unreachable. Making key fields final, as we did here, prevents that problem.
HashMap vs LinkedHashMap vs TreeMap
- HashMap – fastest, no ordering. Use it by default.
- LinkedHashMap – keeps insertion order, slightly more memory. Good for menus or recently used items.
- TreeMap – keeps keys sorted, operations are O(log n). Good for reports sorted by name or date.
Common HashMap Mistakes
- Assuming order. Never rely on the print order of a HashMap; use LinkedHashMap or TreeMap when order matters.
- Unboxing a null.
int score = scores.get("Dan");throws aNullPointerExceptionwhen the key is missing. UsegetOrDefault(). - Modifying the map while looping. Calling
map.remove()inside a for-each loop can throw aConcurrentModificationException. Usemap.entrySet().removeIf(...)instead. - Custom keys without equals() and hashCode(). Lookups silently fail, as explained in Step 4.
Conclusion
HashMap is one of the most useful classes in Java. With just put(), get() and getOrDefault() you can already solve many problems, and the newer methods like merge() and computeIfAbsent() make counting and grouping short and readable. Practice by building a small phonebook, an inventory counter, or a grade lookup using the examples above. You can download all four example programs below.
Happy coding!