HashMap

Reviewed & published by Brayan K

An ArrayList finds items by position. But what if you want to find a person's phone number by their name? A HashMap stores key→value pairs and looks any value up by its key, instantly — like a real dictionary or phone book.

Part of the free Java course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Keys and Values

A HashMap holds pairs. Each pair has a key (what you look up by) and a value (what you get back). Keys are unique; values can repeat.

💡 Analogy: A real dictionary maps a word (key) to its definition (value). You don't scan every page — you jump straight to the word. A HashMap does the same: get("Alice") goes directly to Alice's entry without checking everyone else.

You declare two types in the angle brackets — the key type and the value type. Both must be objects, so use wrapper classes for primitives:

import java.util.HashMap;

HashMap<String, String>  phoneBook = new HashMap<>(); // name -> number
HashMap<String, Integer> ages      = new HashMap<>(); // name -> age
HashMap<Integer, String> idToName  = new HashMap<>(); // id   -> name

2️⃣ The Core Methods

MethodWhat it does
put(k, v)Add the pair, or overwrite if k exists
get(k)Value for k, or null if absent
getOrDefault(k, d)Value for k, or d if absent
containsKey(k)Is there an entry for key k?
containsValue(v)Does any entry hold value v?
remove(k)Delete the entry for k
size()Number of pairs
keySet()All keys (for looping)
entrySet()All key/value pairs (for looping)
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        // A HashMap stores KEY -> VALUE pairs. Here: name -> phone number.
        HashMap<String, String> phoneBook = new HashMap<>();

        phoneBook.put("Alice", "555-0101");   // add or update
        phoneBook.put("Bob",   "555-0202");
        phoneBook.put("Carol", "555-0303");

        // Look up by key — instant, no scanning the whole collection
        System.out.println("Alice -> " + phoneBook.get("Alice"));

        // get() returns null for a missing key
        System.out.println("Dave  -> " + phoneBook.get("Dave"));

        // getOrDefault avoids the null
        System.out.println("Dave  -> " + phoneBook.getOrDefault("Dave", "unknown"));

        // Membership checks
        System.out.println("Has Bob?   " + phoneBook.containsKey("Bob"));
        System.out.println("Size:      " + phoneBook.size());

        // put with an existing key OVERWRITES the old value
        phoneBook.put("Alice", "555-9999");
        System.out.println("Alice now -> " + phoneBook.get("Alice"));

        phoneBook.remove("Bob");
        System.out.println("After remove, has Bob? " + phoneBook.containsKey("Bob"));
    }
}

3️⃣ Looping Over a HashMap

To visit every pair, loop over entrySet() and read each entry's key and value. To visit only keys, loop over keySet().

for (Map.Entry<String, Integer> e : map.entrySet()) {
    System.out.println(e.getKey() + " = " + e.getValue());
}
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        HashMap<String, Integer> stock = new HashMap<>();
        stock.put("apples", 12);
        stock.put("bananas", 5);
        stock.put("cherries", 30);

        // Loop over every key/value pair
        for (Map.Entry<String, Integer> entry : stock.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        // Loop over just the keys
        int totalItems = 0;
        for (String fruit : stock.keySet()) {
            totalItems += stock.get(fruit);
        }
        System.out.println("Total items in stock: " + totalItems);
    }
}

4️⃣ The Tally Pattern (Counting Things)

The single most common HashMap pattern is counting occurrences: words in a sentence, votes per candidate, clicks per page. The trick is getOrDefault:

counts.put(word, counts.getOrDefault(word, 0) + 1);
//          ↑ key      ↑ current count (0 first time) + 1

The first time a key is seen, getOrDefault returns the default 0, so the count becomes 1. Every later time, it returns the existing count and adds one. Clean and bug-free, with no separate "is this the first time?" check.

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

public class Main {
    public static void main(String[] args) {
        // CLASSIC use case: count how many times each word appears.
        String text = "the cat sat on the mat the cat ran";
        String[] words = text.split(" ");

        HashMap<String, Integer> counts = new HashMap<>();
        for (String word : words) {
            // getOrDefault makes the "first time we've seen it" case clean:
            counts.put(word, counts.getOrDefault(word, 0) + 1);
        }

        for (Map.Entry<String, Integer> e : counts.entrySet()) {
            System.out.println(e.getKey() + " -> " + e.getValue());
        }

        // Find the most frequent word
        String top = "";
        int best = 0;
        for (Map.Entry<String, Integer> e : counts.entrySet()) {
            if (e.getValue() > best) {
                best = e.getValue();
                top = e.getKey();
            }
        }
        System.out.println("Most common: '" + top + "' (" + best + " times)");
    }
}
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        // 🎯 YOUR TURN — replace each ___ using the hint beside it.

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

        // 1) Store a value under a key. The same call also OVERWRITES.
        stock.___("bolt", 40);                 // 👉 replace ___ with put
        stock.put("nut", 120);
        stock.put("washer", 0);

        // 2) Read it back by key.
        System.out.println("Bolts: " + stock.___("bolt"));   // 👉 replace ___ with get

        // 3) A key that is missing gives null — unless you supply a fallback.
        System.out.println("Screws: " + stock.___("screw", 0));  // 👉 replace ___ with getOrDefault

        // 4) Present at all? Note that "present" and "not zero" differ.
        System.out.println("Has washer? " + stock.___("washer"));  // 👉 replace ___ with containsKey

        stock.put("bolt", 35);                 // same key: replaces 40

        // 5) Add to whatever is already there, in one call.
        stock.___("nut", 5, Integer::sum);     // 👉 replace ___ with merge
        stock.remove("washer");

        System.out.println("Bolts now: " + stock.get("bolt"));
        System.out.println("Nuts now:  " + stock.get("nut"));
        System.out.println("Size: " + stock.size());

        // A HashMap has NO order, so sort the keys before printing them.
        for (String key : new java.util.TreeSet<>(stock.keySet())) {
            System.out.println("  " + key + " -> " + stock.get(key));
        }
    }
}

🧩 Reorder Challenge

Reorder these lines to store one age and look it up.

System.out.println(ages.get("Sam"));
ages.put("Sam", 28);
HashMap<String, Integer> ages = new HashMap<>();
HashMap<String, Integer> ages = new HashMap<>();
ages.put("Sam", 28);
System.out.println(ages.get("Sam"));

Why: The map must exist before you put into it, and the pair must be stored before get can retrieve it. If you reversed put and get, the lookup would print null. Output: 28.

🧠 Quick Recall

1. What does this print?

HashMap<String, Integer> m = new HashMap<>();
m.put("a", 1);
m.put("a", 5);
System.out.println(m.size());

1. Keys are unique, so the second put("a", 5) overwrites the value rather than adding a new entry.

2. What does this print?

HashMap<String, Integer> m = new HashMap<>();
System.out.println(m.getOrDefault("x", -1));

-1. The key "x" is absent, so getOrDefault returns the supplied default instead of null.

3. What does this print?

HashMap<String, Integer> m = new HashMap<>();
m.put("k", m.getOrDefault("k", 0) + 1);
m.put("k", m.getOrDefault("k", 0) + 1);
System.out.println(m.get("k"));

2. First put: 0 + 1 = 1. Second put: 1 + 1 = 2. That's the tally pattern running twice.

Common Beginner Mistakes

📋 Quick Reference

MethodDescriptionExample
new HashMap<>()Create an empty mapHashMap<String, Integer> m = new HashMap<>();
put(k, v)Add pair, or overwrite if k existsm.put("a", 1)
get(k)Value for k, or null if absentm.get("a")
getOrDefault(k, d)Value for k, or d if absentm.getOrDefault("z", 0)
containsKey(k)Is there an entry for key k?m.containsKey("a")
containsValue(v)Does any entry hold value v?m.containsValue(1)
remove(k)Delete the entry for km.remove("a")
size()Number of key-value pairsm.size()
keySet()All keys (for looping)for (String k : m.keySet())
values()All values (for looping)m.values()
entrySet()All key-value pairsfor (Map.Entry<K,V> e : m.entrySet())
e.getKey() / e.getValue()Read a pair while iteratinge.getKey()
getOrDefault(k,0)+1Tally / count patternm.put(w, m.getOrDefault(w,0)+1)
merge(k, 1, Integer::sum)Alternative tally one-linerm.merge(w, 1, Integer::sum)

🎉 Lesson Complete!

You now command Java's most useful collection for lookups: put and get pairs, dodge null with getOrDefault, check membership with containsKey, iterate with entrySet/keySet, and count things with the tally pattern.

Practice quiz

What does a HashMap store?

  • Only values, by index
  • Key-value pairs
  • Unique values only
  • Sorted numbers

Answer: Key-value pairs. A HashMap stores key-value pairs and looks values up by key.

What happens when you put the same key twice?

  • It adds a second entry
  • It overwrites the old value
  • It throws an exception
  • It ignores the new value

Answer: It overwrites the old value. Keys are unique; a second put with the same key overwrites the value.

After m.put('a',1); m.put('a',5); what is m.size()?

  • 0
  • 1
  • 2
  • 5

Answer: 1. Both puts use key 'a', so there is just one entry — size is 1.

What does get(key) return for a key that is not present?

  • 0
  • An empty string
  • null
  • It throws

Answer: null. get returns null for a missing key, which can cause a NullPointerException if used carelessly.

Which method returns a fallback instead of null for a missing key?

  • get
  • getOrDefault
  • containsKey
  • orElse

Answer: getOrDefault. getOrDefault(key, fallback) returns the fallback when the key is absent.

Which key type is illegal for a HashMap?

  • String
  • Integer
  • int
  • Character

Answer: int. Keys must be objects; use the wrapper Integer, not the primitive int.

How do you loop over every key-value pair?

  • for (x : map)
  • for (Map.Entry<K,V> e : map.entrySet())
  • for (i = 0; i < map.size; i++)
  • map.forEachKey()

Answer: for (Map.Entry<K,V> e : map.entrySet()). Iterate map.entrySet() and read e.getKey()/e.getValue().

Is a HashMap's iteration order guaranteed?

  • Yes, insertion order
  • Yes, sorted order
  • No, it can look random
  • Yes, reverse order

Answer: No, it can look random. HashMap order is not guaranteed; use LinkedHashMap for insertion order or TreeMap for sorted.

Which line correctly implements the word-count tally pattern?

  • counts.add(word)
  • counts.put(word, counts.getOrDefault(word, 0) + 1)
  • counts.increment(word)
  • counts.put(word, counts.get(word) + 1)

Answer: counts.put(word, counts.getOrDefault(word, 0) + 1). getOrDefault(word, 0) + 1 handles the first-time case cleanly without a null check.

Which class keeps keys in sorted order?

  • HashMap
  • LinkedHashMap
  • TreeMap
  • ArrayMap

Answer: TreeMap. TreeMap stores keys in sorted order.

Continue this course

Frequently asked questions

What is a HashMap and when should I use one?

A HashMap stores key-value pairs and lets you look up a value by its key almost instantly, no matter how big the map is. Use it whenever you want to associate one thing with another: a username to a user object, a product code to a price, a word to its count. If you only need a list of values without keys, use an ArrayList instead.

What happens if I put the same key twice?

Keys are unique. Calling put with a key that already exists overwrites the old value with the new one rather than adding a second entry. So map.put("x", 1) followed by map.put("x", 2) leaves the map with a single entry x -> 2. If you need multiple values per key, store a list as the value: HashMap of String to a List.

Why does get() return null, and how do I avoid NullPointerExceptions?

get(key) returns null when the key is not present. If you then call a method on that null you get a NullPointerException. Avoid it with getOrDefault(key, fallback), which returns your fallback when the key is missing, or guard with containsKey(key) before calling get. getOrDefault is especially handy for counting and tallying.

How do I loop over a HashMap, and is the order guaranteed?

Iterate the pairs with for (Map.Entry<K,V> e : map.entrySet()) and call e.getKey() and e.getValue(); or loop map.keySet() for just the keys. The order is NOT guaranteed and can look random, because entries are placed by hash code. If you need keys in insertion order use a LinkedHashMap, and for sorted keys use a TreeMap.

What types can I use for keys and values?

Both must be reference types (objects), so use wrapper classes for primitives: HashMap<String, Integer>, not HashMap<String, int>. Keys should have sensible equals and hashCode methods; String, Integer, and most built-in types already do. Values can be anything, including another collection like an ArrayList or even another HashMap.