HashMap in Java

Learn HashMap in Java with practical examples, explanations, best practices, and real-world coding techniques.

HashMap in Java is a collection that stores data as key-value pairs. Each key identifies a value, allowing applications to retrieve information efficiently without searching through every element. HashMap is part of the Java Collections Framework and is commonly used for lookups, caching, configuration data, grouping, and frequency counting.

Unlike an ArrayList, which is primarily accessed using numeric indexes, a HashMap is accessed using keys. For example, an application can associate a username with a score, a product ID with a product, or a country code with a country name.

What Is HashMap in Java?

HashMap<K, V> stores mappings between a key type K and a value type V. Keys must be unique. If the same key is inserted again, its associated value is replaced.

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

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put("Charlie", 95);

System.out.println(scores);

In this example, the names are keys and the scores are values. The map can retrieve a score directly by supplying the corresponding name.

How HashMap Stores Data

HashMap uses a hashing-based structure to organize key-value entries. When a key is added, Java uses its hash information to determine where the entry should be stored internally.

When a value is requested using a key, the hash information helps locate the corresponding entry without scanning every key in the map.

Hash collisions can occur when different keys map to the same internal location. Java's HashMap implementation handles collisions internally, so developers normally work with the collection through methods such as put(), get(), and remove() rather than managing buckets directly.

Creating a HashMap

A HashMap is commonly declared using the Map interface and initialized with a HashMap implementation.

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

Map<Integer, String> users = new HashMap<>();

users.put(101, "Alice");
users.put(102, "Bob");
users.put(103, "Charlie");

Using Map as the variable type makes the code depend on the interface. This can make it easier to replace the implementation when requirements change.

Adding Key-Value Pairs

The put() method adds a key-value pair to the map.

Map<String, String> countries = new HashMap<>();

countries.put("IN", "India");
countries.put("US", "United States");
countries.put("JP", "Japan");

System.out.println(countries);

If a key already exists, calling put() with that key replaces its existing value.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 80);
scores.put("Alice", 95);

System.out.println(scores.get("Alice"));

The final value associated with Alice is 95.

Getting a Value from HashMap

Use the get() method to retrieve a value using its key.

Map<Integer, String> users = new HashMap<>();

users.put(101, "Alice");
users.put(102, "Bob");

String name = users.get(101);

System.out.println(name);

If the specified key does not exist, get() returns null.

Using getOrDefault()

The getOrDefault() method provides a fallback value when a key is not present.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);

int aliceScore = scores.getOrDefault("Alice", 0);
int bobScore = scores.getOrDefault("Bob", 0);

System.out.println(aliceScore);
System.out.println(bobScore);

This method is particularly useful in counting and aggregation problems because it avoids separate existence checks for every key.

Updating a HashMap Value

A value can be updated simply by calling put() again with the existing key.

Map<String, Integer> inventory = new HashMap<>();

inventory.put("Keyboard", 10);
inventory.put("Mouse", 15);

inventory.put("Keyboard", 25);

System.out.println(inventory);

The key remains the same, while its associated value changes from 10 to 25.

Checking Whether a Key Exists

Use containsKey() when you need to determine whether a particular key exists in the map.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);
scores.put("Bob", 85);

if (scores.containsKey("Alice")) {
    System.out.println("Alice exists");
}

Checking Whether a Value Exists

The containsValue() method checks whether at least one entry contains the specified value.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);
scores.put("Bob", 85);

System.out.println(scores.containsValue(90));
System.out.println(scores.containsValue(100));

Unlike key lookup, searching for a value may require checking multiple entries, so containsValue() is generally O(n).

Removing Entries

Use remove() to delete an entry using its key.

Map<Integer, String> users = new HashMap<>();

users.put(101, "Alice");
users.put(102, "Bob");
users.put(103, "Charlie");

users.remove(102);

System.out.println(users);

Java also provides an overload that removes an entry only when both the key and value match.

users.remove(103, "Charlie");

Iterating Through a HashMap

HashMap provides several ways to iterate over its contents. A common approach is using entrySet(), which gives access to both keys and values.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put("Charlie", 95);

for (Map.Entry<String, Integer> entry : scores.entrySet()) {
    System.out.println(
        entry.getKey() + " = " + entry.getValue()
    );
}

Iterating Over Keys

for (String name : scores.keySet()) {
    System.out.println(name);
}

Iterating Over Values

for (Integer score : scores.values()) {
    System.out.println(score);
}

HashMap does not guarantee a predictable iteration order. If a specific ordering requirement exists, another map implementation such as LinkedHashMap or TreeMap may be more appropriate.

HashMap Size and Empty Check

Use size() to find the number of key-value mappings and isEmpty() to check whether the map contains no entries.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);
scores.put("Bob", 85);

System.out.println(scores.size());
System.out.println(scores.isEmpty());

Clearing a HashMap

The clear() method removes all mappings from the HashMap.

Map<String, Integer> scores = new HashMap<>();

scores.put("Alice", 90);
scores.put("Bob", 85);

scores.clear();

System.out.println(scores);
System.out.println(scores.isEmpty());

HashMap and Null Values

A HashMap permits a single null key and can contain multiple entries whose values are null.

Map<String, String> users = new HashMap<>();

users.put(null, "Unknown");
users.put("Alice", null);

System.out.println(users.get(null));
System.out.println(users.get("Alice"));

Because get() can return null both when a key is absent and when a key is explicitly mapped to null, use containsKey() when that distinction matters.

Frequency Counting with HashMap

One of the most common uses of HashMap in coding problems is counting how frequently each value occurs.

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

public class Main {
    public static void main(String[] args) {
        int[] numbers = {2, 3, 2, 5, 3, 2};

        Map<Integer, Integer> frequency = new HashMap<>();

        for (int number : numbers) {
            frequency.put(
                number,
                frequency.getOrDefault(number, 0) + 1
            );
        }

        System.out.println(frequency);
    }
}

This pattern can be adapted for characters, words, IDs, categories, and many other situations where occurrences need to be counted.

Using compute() and merge()

HashMap also provides methods that make conditional updates more concise. For example, merge() can be used for frequency counting.

Map<String, Integer> frequency = new HashMap<>();

String[] words = {"java", "python", "java", "csharp"};

for (String word : words) {
    frequency.merge(word, 1, Integer::sum);
}

System.out.println(frequency);

These methods are useful when the update logic depends on whether a key already exists.

HashMap with Custom Objects

HashMap can use custom objects as keys or values. When custom objects are used as keys, correct implementations of equals() and hashCode() are important because HashMap relies on these methods to identify equivalent keys.

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

class Product {
    String name;

    Product(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Map<Integer, Product> products = new HashMap<>();

        products.put(101, new Product("Keyboard"));
        products.put(102, new Product("Mouse"));

        Product product = products.get(101);

        System.out.println(product.name);
    }
}

Using simple immutable key types such as strings, numbers, or well-defined value objects can make key behavior easier to reason about.

HashMap Time Complexity

HashMap operations are generally efficient because hashing allows Java to locate entries without scanning the entire collection in the normal case.

Operation Typical Complexity
put() O(1) average
get() O(1) average
containsKey() O(1) average
remove() O(1) average
containsValue() O(n)
Iteration O(n)

The average O(1) complexity assumes well-distributed hashes and normal operation. HashMap performance can be affected by collisions, resizing, and the quality of key implementations.

HashMap vs ArrayList

ArrayList and HashMap solve different lookup problems. The choice depends on whether data is naturally accessed by position or by a key.

Feature ArrayList HashMap
Data model Ordered elements Key-value mappings
Access By index By key
Duplicate values Allowed Allowed
Unique keys Not applicable Required

HashMap vs TreeMap

Both classes implement the Map interface, but they provide different ordering and performance characteristics.

Feature HashMap TreeMap
Ordering No guaranteed iteration order Sorted by keys
get() O(1) average O(log n)
put() O(1) average O(log n)
Main purpose Fast key lookup Sorted key operations

Common HashMap Mistakes

  • Assuming HashMap preserves insertion order.
  • Using a HashMap when sorted key order is a requirement.
  • Expecting get() to distinguish a missing key from a key mapped to null.
  • Using mutable objects as keys without carefully handling equals() and hashCode().
  • Assuming containsValue() is as efficient as key lookup.
  • Forgetting that keys are unique and inserting the same key replaces its previous value.
  • Using HashMap when a Set is sufficient for simple membership checking.
  • Ignoring thread-safety requirements when a map is accessed concurrently.

When Should You Use HashMap?

HashMap is appropriate when data naturally forms a relationship between a unique key and an associated value.

  • You need fast average-case lookup by key.
  • Each record has a unique identifier.
  • Ordering is not required.
  • You need to count frequencies or group values.
  • You need an in-memory lookup or cache.
  • You need to associate IDs with application objects.

Practical Example: User Lookup

A backend application might store users by their unique ID so that a user can be retrieved without scanning an entire list.

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

class User {
    int id;
    String name;

    User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Map<Integer, User> users = new HashMap<>();

        users.put(101, new User(101, "Alice"));
        users.put(102, new User(102, "Bob"));
        users.put(103, new User(103, "Charlie"));

        User user = users.get(102);

        if (user != null) {
            System.out.println("User: " + user.name);
        }
    }
}

Key Takeaways

  • HashMap stores data as key-value pairs.
  • Keys are unique, while values can be duplicated.
  • put() adds or updates a mapping.
  • get() retrieves a value using its key.
  • containsKey() checks whether a key exists.
  • remove() deletes a mapping.
  • HashMap provides O(1) average-case lookup, insertion, and removal under typical conditions.
  • HashMap does not guarantee a predictable iteration order.
  • HashMap is widely useful for frequency counting, caching, grouping, and key-based lookups.

Code Examples

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

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();

        scores.put("Alice", 90);
        scores.put("Bob", 85);
        scores.put("Charlie", 95);

        System.out.println(scores.get("Bob"));
    }
}
    
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> inventory = new HashMap<>();

        inventory.put("Keyboard", 10);
        inventory.put("Mouse", 15);

        inventory.put("Keyboard", 25);
        inventory.remove("Mouse");

        System.out.println(inventory);
    }
}
    
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {2, 3, 2, 5, 3, 2};

        Map<Integer, Integer> frequency = new HashMap<>();

        for (int number : numbers) {
            frequency.put(
                number,
                frequency.getOrDefault(number, 0) + 1
            );
        }

        System.out.println(frequency);
    }
}
    
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();

        scores.put("Alice", 90);
        scores.put("Bob", 85);
        scores.put("Charlie", 95);

        for (Map.Entry<String, Integer> entry : scores.entrySet()) {
            System.out.println(
                entry.getKey() + " = " + entry.getValue()
            );
        }
    }
}
    

Pro Tip

Use HashMap when your primary operation is finding data by a unique key. For sorted keys, consider TreeMap; for preserving insertion order, consider LinkedHashMap; and when you only need unique values, consider HashSet.

🎨 IgKnight Docs

Master HTML, CSS, JS, Python, .NET and more with easy-to-follow lessons and practical code examples.

© 2025 IgKnight Learning Platform. All rights reserved.