1. Introduction
In real life, we often face situations where each unique “key” needs to be associated with some “value.” A phone book stores a person’s name and phone number, a dictionary links a word to its translation, and in a grade table each student has their own name and a corresponding score.
In Java, there is the Map interface for such tasks. It’s a collection that stores “key–value” pairs.
Main properties of Map:
- Each key is unique (no duplicates allowed).
- A key can map to only one value.
- Values can repeat.
Consider an analogy. If a list (List) is like a cafeteria queue (everyone stands in their position, and you can access by index), then a map (Map) is like a locker with compartments: each compartment has a number (the key), and it contains something of its own (the value).
Map interface: basic operations
The Map interface declares the core methods for working with key–value pairs:
| Method | Description |
|---|---|
|
Add/replace a value by key |
|
Get a value by key |
|
Remove a pair by key |
|
Check whether the key exists |
|
Check whether the value exists |
|
The number of pairs in the map |
|
Check whether the Map is empty |
|
Remove all pairs |
Types K and V are generic parameters: K (Key) is the key type, V (Value) is the value type.
3. HashMap class: fast access by key
What is HashMap?
HashMap is the most popular implementation of the Map interface. It provides fast access to values by key.
Important: HashMap does not guarantee element order! If you add keys in a certain order, iteration may produce a different order.
How to create a HashMap?
import java.util.HashMap;
import java.util.Map;
public class Example {
public static void main(String[] args) {
// Create a map: key - String, value - Integer
Map<String, Integer> ages = new HashMap<>();
// Add elements
ages.put("John", 25);
ages.put("Peter", 30);
ages.put("Mary", 22);
// Get a value by key
int johnAge = ages.get("John");
System.out.println("John's age: " + johnAge); // 25
// Check key presence
if (ages.containsKey("Mary")) {
System.out.println("Mary is in the list!");
}
// Remove an element
ages.remove("Peter");
// Iterate over all key-value pairs
for (String name : ages.keySet()) {
System.out.println(name + ": " + ages.get(name));
}
}
}
Output:
John's age: 25
Mary is in the list!
John: 25
Mary: 22
HashMap specifics
The main thing to remember: keys in a HashMap are always unique. If you put a new element with an existing key, the old value will be replaced with the new one.
Values can repeat: several different keys can point to the same value.
Another important point is element order. HashMap doesn’t care about insertion order. When printing, entries may be shuffled — that’s expected behavior.
4. TreeMap class: sorting by key
Unlike HashMap, the TreeMap class stores elements in key-sorted order.
When to use TreeMap?
When it’s important for elements to follow ascending (or descending) key order. For example, if you want to print a phone book alphabetically.
Example:
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
Map<String, String> phoneBook = new TreeMap<>();
phoneBook.put("John", "+1-900-123-45-67");
phoneBook.put("Mary", "+1-900-555-55-55");
phoneBook.put("Peter", "+1-900-222-33-44");
for (String name : phoneBook.keySet()) {
System.out.println(name + ": " + phoneBook.get(name));
}
}
}
Output:
Mary: +1-900-555-55-55
Peter: +1-900-222-33-44
John: +1-900-123-45-67
Note: the keys are sorted alphabetically.
5. Basic operations with Map
Adding and replacing elements
Map<String, Integer> scores = new HashMap<>();
scores.put("Anna", 90);
scores.put("Jack", 85);
scores.put("Anna", 95); // Will overwrite the value for "Anna"
Getting a value
Integer annaScore = scores.get("Anna"); // 95
Integer unknown = scores.get("John"); // null if there is no such key
Checking for a key or value
scores.containsKey("Jack"); // true
scores.containsValue(85); // true
Removing a pair by key
scores.remove("Jack");
Map size and clearing
int size = scores.size();
scores.clear(); // Removes all elements
5. Iterating over Map elements
Map is not a list; there are no indices. But you can iterate:
By keys:
for (String key : scores.keySet()) {
System.out.println("Key: " + key + ", Value: " + scores.get(key));
}
By values:
for (Integer value : scores.values()) {
System.out.println("Value: " + value);
}
By key–value pairs (the best way):
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " => " + value);
}
When to use HashMap, and when — TreeMap?
HashMap is the general-purpose “by default” choice. If key order doesn’t matter and speed is the priority, you almost always use it.
TreeMap is useful when you need order. It automatically keeps keys sorted and lets you quickly find the minimum/maximum key or work with ranges.
Bottom line: in 90% of cases, pick HashMap. When the data needs to be “in order” right away, use TreeMap.
6. Map usage examples
Example 1: Phone book
Map<String, String> phoneBook = new HashMap<>();
phoneBook.put("Kate", "+1-999-111-22-33");
phoneBook.put("Oliver", "+1-999-222-33-44");
phoneBook.put("Kate", "+1-999-555-66-77"); // Kate's old number will be replaced with the new one
for (Map.Entry<String, String> entry : phoneBook.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
Output:
Oliver: +1-999-222-33-44
Kate: +1-999-555-66-77
Example 2: Counting word occurrences
Suppose we have a list of words and want to know how many times each word occurs:
import java.util.*;
public class WordCount {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "apple", "pear", "banana", "apple");
Map<String, Integer> counts = new HashMap<>();
for (String word : words) {
int oldCount = counts.getOrDefault(word, 0); // if there is no such key - 0
counts.put(word, oldCount + 1);
}
System.out.println(counts); // {pear=1, apple=3, banana=2}
}
}
7. Common mistakes when working with Map
Mistake #1: Confusing keys and values. Beginners often try to get a value by index, as in a list, or forget that keys must be unique. Map has no indices — only keys.
Mistake #2: Using null keys and values. HashMap allows a null key, but TreeMap does not (it will throw NullPointerException). Values can be null in both implementations, but that’s rarely useful.
Mistake #3: Expecting element order in HashMap. HashMap doesn’t guarantee any order. If you need order, use LinkedHashMap (preserves insertion order) or TreeMap (sorts by key).
Mistake #4: Modifying a Map during iteration. If you iterate over a Map in a loop and simultaneously add/remove elements, you may get a ConcurrentModificationException. For such tasks, use an iterator with the remove() method or specialised collections.
Mistake #5: Comparing keys and values with == instead of equals. Map uses the equals method to compare keys (and values). If you create your own key classes, be sure to override equals and hashCode.
GO TO FULL VERSION