Java HashMap: A Complete Guide with Examples and Exercises
In Java, the HashMap
class is part of the java.util
package and is one of the most commonly used classes for storing data in the form of key-value pairs. A HashMap
allows you to quickly look up values based on their associated keys, offering a fast and efficient way to store and retrieve data. This guide will explore the core concepts of HashMap
, demonstrate its usage with examples, and provide exercises to reinforce the concepts.
Table of Contents
- Introduction to HashMap
- Creating a HashMap
- Basic HashMap Operations
- Adding Elements
- Accessing Elements
- Removing Elements
- Iterating Over a HashMap
- HashMap vs Hashtable
- Custom Key and Value Types
- Common HashMap Methods
- Exercises
1. Introduction to HashMap
A HashMap
is a collection of key-value pairs, where each key is unique and maps to exactly one value. It implements the Map
interface and is a part of Java’s collection framework. The keys in a HashMap
must be unique, and values can be duplicated. The internal data structure of a HashMap
is backed by a hash table, allowing for fast access to elements via their keys.
Features of HashMap:
- Key-Value Mapping: Each entry consists of a key and a corresponding value.
- Fast Lookup: Provides constant-time performance (O(1)) for basic operations like
get()
,put()
, andremove()
, assuming the hash function distributes the elements properly. - Null Keys and Values:
HashMap
allows one null key and any number of null values. - Non-Synchronized: It is not thread-safe, meaning that it is not suitable for multi-threaded environments unless synchronized externally.
2. Creating a HashMap
You can create a HashMap
using the default constructor or with an initial capacity and load factor. The default constructor creates an empty HashMap
, while you can specify the initial capacity and load factor to optimize performance if you know the size of the map in advance.
Example 1: Creating an Empty HashMap
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Creating an empty HashMap
HashMap<String, Integer> map = new HashMap<>();
// Adding elements to the HashMap
map.put("Alice", 25);
map.put("Bob", 30);
map.put("Charlie", 35);
// Printing the HashMap
System.out.println("HashMap: " + map);
}
}
Output:
HashMap: {Alice=25, Bob=30, Charlie=35}
Example 2: Creating a HashMap with Initial Capacity and Load Factor
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Creating a HashMap with an initial capacity of 16 and load factor 0.75
HashMap<String, Integer> map = new HashMap<>(16, 0.75f);
// Adding elements
map.put("John", 28);
map.put("Jane", 32);
// Printing the HashMap
System.out.println("HashMap: " + map);
}
}
3. Basic HashMap Operations
Adding Elements
You can add key-value pairs to the HashMap
using the put()
method.
Example: Adding Elements
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
// Adding elements to the HashMap
map.put("Apple", "Green");
map.put("Banana", "Yellow");
map.put("Grapes", "Purple");
System.out.println("HashMap: " + map);
}
}
Output:
HashMap: {Apple=Green, Banana=Yellow, Grapes=Purple}
Accessing Elements
You can access the value associated with a key using the get()
method. If the key is not present, it returns null
.
Example: Accessing Elements
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("Apple", "Green");
map.put("Banana", "Yellow");
// Accessing values using keys
System.out.println("Apple is: " + map.get("Apple"));
System.out.println("Banana is: " + map.get("Banana"));
System.out.println("Orange is: " + map.get("Orange")); // Returns null
}
}
Output:
Apple is: Green
Banana is: Yellow
Orange is: null
Removing Elements
To remove a key-value pair, use the remove()
method. You can remove an entry by key or by key-value pair.
Example: Removing Elements
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);
// Removing an entry by key
map.remove("Two");
// Removing an entry by key and value
map.remove("Three", 3);
System.out.println("HashMap after removal: " + map);
}
}
Output:
HashMap after removal: {One=1}
4. Iterating Over a HashMap
There are several ways to iterate over a HashMap
to access its keys and values.
Example 1: Using for-each
Loop
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("Red", "Apple");
map.put("Yellow", "Banana");
// Iterating using for-each loop
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
}
}
Output:
Red: Apple
Yellow: Banana
Example 2: Using entrySet()
The entrySet()
method returns a set of Map.Entry
objects, which you can iterate over.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
// Iterating using entrySet()
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
Output:
Alice: 25
Bob: 30
5. HashMap vs Hashtable
Although HashMap
and Hashtable
both store data in key-value pairs and are part of the Map
interface, they differ in several ways:
Feature | HashMap | Hashtable |
---|---|---|
Thread Safety | Not thread-safe | Thread-safe |
Null Keys/Values | Allows one null key and null values | Does not allow null keys or values |
Performance | Generally faster due to lack of synchronization | Slower due to synchronized methods |
Iteration Order | Iteration order is not guaranteed | Iteration order is not guaranteed |
HashMap
is generally preferred over Hashtable
because it is faster and more flexible for non-concurrent use cases. If thread safety is required, you can use ConcurrentHashMap
instead.
6. Custom Key and Value Types
You can use custom objects as keys and values in a HashMap
. However, when using custom objects as keys, you must override the hashCode()
and equals()
methods to ensure correct behavior.
Example: Using Custom Objects as Keys
import java.util.HashMap;
class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Student student = (Student) obj;
return id == student.id && name.equals(student.name);
}
@Override
public int hashCode() {
return 31 * id + name.hashCode();
}
}
public class Main {
public static void main(String[] args) {
HashMap<Student, String> studentMap = new HashMap<>();
Student s1 = new Student(1, "Alice");
Student s2 = new Student(2, "Bob");
studentMap.put(s1, "Grade A");
studentMap.put(s2, "Grade B");
// Accessing values using custom objects as keys
System.out.println("Student: " + s1.name + ", "
+ studentMap.get(s1));
System.out.println("Student: " + s2.name + ", " + studentMap.get(s2));
}
}
7. Common HashMap Methods
Here are some commonly used methods of HashMap
:
- put(K key, V value): Adds a key-value pair.
- get(Object key): Retrieves the value associated with a key.
- remove(Object key): Removes the entry for the specified key.
- containsKey(Object key): Checks if the map contains a specific key.
- containsValue(Object value): Checks if the map contains a specific value.
- size(): Returns the number of key-value pairs in the map.
- clear(): Removes all entries from the map.
8. Exercises
Exercise 1: Create a HashMap of Employee IDs and Names
- Create a
HashMap
to store employee IDs as keys and employee names as values. - Add 5 employee records.
- Retrieve and print the name of an employee given their ID.
Exercise 2: Remove an Entry from HashMap
- Create a
HashMap
that maps city names to their populations. - Remove a city from the map by its name.
- Print the updated map.
Exercise 3: Check If Key or Value Exists
- Create a
HashMap
to store book titles and their authors. - Check if a particular book title exists in the map.
- Check if a specific author is in the map.
Solution for Exercise 1
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> employees = new HashMap<>();
// Adding employees
employees.put(101, "Alice");
employees.put(102, "Bob");
employees.put(103, "Charlie");
// Retrieving an employee by ID
System.out.println("Employee with ID 102: " + employees.get(102));
}
}
Conclusion
The HashMap
class is a powerful and flexible data structure for storing key-value pairs in Java. It allows for fast lookups, insertions, and deletions. By understanding how to use HashMap
efficiently and customizing it to your needs, you can handle many different types of data storage and retrieval scenarios. Practice the exercises to become proficient in using HashMap
and its various methods.