HashMap in Java

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

  1. Introduction to HashMap
  2. Creating a HashMap
  3. Basic HashMap Operations
  • Adding Elements
  • Accessing Elements
  • Removing Elements
  1. Iterating Over a HashMap
  2. HashMap vs Hashtable
  3. Custom Key and Value Types
  4. Common HashMap Methods
  5. 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(), and remove(), 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:

FeatureHashMapHashtable
Thread SafetyNot thread-safeThread-safe
Null Keys/ValuesAllows one null key and null valuesDoes not allow null keys or values
PerformanceGenerally faster due to lack of synchronizationSlower due to synchronized methods
Iteration OrderIteration order is not guaranteedIteration 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

  1. Create a HashMap to store employee IDs as keys and employee names as values.
  2. Add 5 employee records.
  3. Retrieve and print the name of an employee given their ID.

Exercise 2: Remove an Entry from HashMap

  1. Create a HashMap that maps city names to their populations.
  2. Remove a city from the map by its name.
  3. Print the updated map.

Exercise 3: Check If Key or Value Exists

  1. Create a HashMap to store book titles and their authors.
  2. Check if a particular book title exists in the map.
  3. 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top