Java HashMap

Learn how to store and retrieve data efficiently using key-value pairs with HashMap, one of the most powerful collections in Java.

What is HashMap?

HashMap is a collection that stores data in key-value pairs, where each unique key maps to exactly one value. It's part of the java.util package and implements the Map interface. Think of it like a real dictionary where you look up a word (key) to find its meaning (value)!

For example, you could store student names as keys and their marks as values, or store country names as keys and their capitals as values.

  • Key-Value Storage: Each entry consists of a unique key and its associated value
  • Fast Retrieval: Access values instantly using their keys (O(1) time complexity)
  • No Duplicate Keys: Each key can appear only once, but values can be duplicated
  • Null Allowed: Can store one null key and multiple null values
  • Unordered: Does not maintain any order of elements

๐Ÿ’ก Key Point: HashMap is perfect when you need to quickly look up information using a unique identifier, like finding a phone number by name or getting a product price by its code.

Creating and Using HashMap

Here's how to create a HashMap and perform basic operations:

Example: HashMap Basic Operations

import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        // Creating a HashMap (Country -> Capital)
        HashMap capitals = new HashMap<>();
        
        // Adding key-value pairs
        capitals.put("India", "New Delhi");
        capitals.put("USA", "Washington DC");
        capitals.put("Japan", "Tokyo");
        capitals.put("France", "Paris");
        
        // Display HashMap
        System.out.println("Capitals: " + capitals);
        
        // Getting a value by key
        System.out.println("Capital of India: " + capitals.get("India"));
        
        // Checking if a key exists
        System.out.println("Has USA? " + capitals.containsKey("USA"));
        
        // Checking if a value exists
        System.out.println("Has Berlin? " + capitals.containsValue("Berlin"));
        
        // Updating a value
        capitals.put("Japan", "Kyoto");
        System.out.println("Updated Japan: " + capitals.get("Japan"));
        
        // Removing an entry
        capitals.remove("France");
        System.out.println("After removal: " + capitals);
        
        // Size of HashMap
        System.out.println("Total entries: " + capitals.size());
    }
}
Output:
Capitals: {USA=Washington DC, France=Paris, Japan=Tokyo, India=New Delhi}
Capital of India: New Delhi
Has USA? true
Has Berlin? false
Updated Japan: Kyoto
After removal: {USA=Washington DC, Japan=Kyoto, India=New Delhi}
Total entries: 3

Explanation:

  • HashMap<String, String> - First type is key, second is value
  • put(key, value) - Adds or updates a key-value pair
  • get(key) - Retrieves the value associated with the key
  • containsKey() - Checks if a specific key exists
  • containsValue() - Checks if a specific value exists
  • remove(key) - Removes the entry with the specified key

Looping Through HashMap

There are multiple ways to iterate through a HashMap. Here are the most common methods:

Example: Different Ways to Loop

import java.util.HashMap;
import java.util.Map;

public class HashMapLoopExample {
    public static void main(String[] args) {
        HashMap marks = new HashMap<>();
        marks.put("Rahul", 85);
        marks.put("Priya", 92);
        marks.put("Amit", 78);
        marks.put("Sneha", 95);
        
        // Method 1: Loop through keys only
        System.out.println("Method 1: Using keySet()");
        for (String name : marks.keySet()) {
            System.out.println(name + ": " + marks.get(name));
        }
        
        // Method 2: Loop through values only
        System.out.println("\nMethod 2: Using values()");
        for (Integer mark : marks.values()) {
            System.out.println("Mark: " + mark);
        }
        
        // Method 3: Loop through key-value pairs
        System.out.println("\nMethod 3: Using entrySet()");
        for (Map.Entry entry : marks.entrySet()) {
            System.out.println(entry.getKey() + " scored " + entry.getValue());
        }
        
        // Method 4: forEach with Lambda (Java 8+)
        System.out.println("\nMethod 4: Using forEach()");
        marks.forEach((name, mark) -> 
            System.out.println(name + " = " + mark)
        );
    }
}
Output:
Method 1: Using keySet()
Rahul: 85
Priya: 92
Amit: 78
Sneha: 95

Method 2: Using values()
Mark: 85
Mark: 92
Mark: 78
Mark: 95

Method 3: Using entrySet()
Rahul scored 85
Priya scored 92
Amit scored 78
Sneha scored 95

Method 4: Using forEach()
Rahul = 85
Priya = 92
Amit = 78
Sneha = 95

Explanation:

  • keySet() - Returns all keys, then use get() for values
  • values() - Returns only values (no access to keys)
  • entrySet() - Returns key-value pairs (most efficient for both)
  • forEach() - Modern Java 8+ approach with lambda expressions

Common HashMap Methods

1. Adding and Updating

Insert new entries or update existing ones in the HashMap.

Methods: put(key, value), putAll(map), putIfAbsent(key, value)

2. Accessing Data

Retrieve values or check for the presence of keys and values.

Methods: get(key), getOrDefault(key, defaultValue), containsKey(key), containsValue(value)

3. Removing Data

Delete specific entries or clear the entire HashMap.

Methods: remove(key), remove(key, value), clear()

4. Utility Methods

Get information about the HashMap structure and contents.

Methods: size(), isEmpty(), replace(key, value), keySet(), values(), entrySet()

Practical Example: Student Grade Manager

Let's create a real-world application that manages student grades using HashMap:

Example: Grade Management System

import java.util.HashMap;

public class GradeManager {
    public static void main(String[] args) {
        HashMap grades = new HashMap<>();
        
        // Adding student grades
        grades.put("Alice", 88);
        grades.put("Bob", 75);
        grades.put("Charlie", 92);
        grades.put("Diana", 85);
        
        System.out.println("=== Grade Report ===");
        
        // Calculate and display grades with letter equivalents
        for (String student : grades.keySet()) {
            int marks = grades.get(student);
            String grade = getLetterGrade(marks);
            System.out.println(student + ": " + marks + " (" + grade + ")");
        }
        
        // Find highest scorer
        String topStudent = "";
        int highestMarks = 0;
        
        for (String student : grades.keySet()) {
            int marks = grades.get(student);
            if (marks > highestMarks) {
                highestMarks = marks;
                topStudent = student;
            }
        }
        
        System.out.println("\n๐Ÿ† Top Scorer: " + topStudent + 
                           " with " + highestMarks + " marks");
        
        // Calculate average
        int total = 0;
        for (int mark : grades.values()) {
            total += mark;
        }
        double average = (double) total / grades.size();
        System.out.println("๐Ÿ“Š Class Average: " + 
                           String.format("%.2f", average));
    }
    
    static String getLetterGrade(int marks) {
        if (marks >= 90) return "A+";
        else if (marks >= 80) return "A";
        else if (marks >= 70) return "B";
        else if (marks >= 60) return "C";
        else return "D";
    }
}
Output:
=== Grade Report ===
Alice: 88 (A)
Bob: 75 (B)
Charlie: 92 (A+)
Diana: 85 (A)

๐Ÿ† Top Scorer: Charlie with 92 marks
๐Ÿ“Š Class Average: 85.00

Explanation:

  • HashMap stores student names as keys and their marks as values
  • Easy to look up any student's grade instantly using their name
  • Can iterate through all entries to calculate statistics
  • Perfect for scenarios where you need quick lookups by unique identifiers

Important Points to Remember

Keep these key characteristics in mind when working with HashMap:

  • Keys Must Be Unique: If you add a key that already exists, it will update the old value
  • Null Key: HashMap allows one null key and multiple null values
  • Not Thread-Safe: Use ConcurrentHashMap for multi-threaded applications
  • Unordered: Elements are not stored in any particular order
  • Fast Performance: O(1) time complexity for get() and put() operations

โš ๏ธ Common Mistake: Trying to use mutable objects as keys can lead to unexpected behavior. Always use immutable objects like String, Integer, or custom immutable classes as HashMap keys.

HashMap vs Other Collections

Understanding when to use HashMap compared to other collections:

Quick Comparison

Feature              HashMap              ArrayList            HashSet
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Storage              Key-Value pairs      Single values         Single values
Duplicates           Keys: No, Values: Yes  Yes                   No
Ordering             No order             Insertion order       No order
Access Method        By key               By index              Contains check
Use Case             Lookups by ID        Ordered list          Unique items

๐ŸŽฏ When to Use HashMap: Choose HashMap when you need to store data in pairs with a unique identifier (key) for quick lookups. Examples: phone directory, user profiles, product catalogs, configuration settings.