Java HashMap, TreeMap and LinkedHashMap

A Java Map associates each key with at most one value.

Lesson 49 of 127Intermediate15 min read

A Java Map associates each key with at most one value. HashMap, LinkedHashMap and TreeMap offer different lookup and ordering behavior. Values may repeat, but inserting an existing key replaces its association instead of creating a second independent entry.

Review the related foundation lesson when you need a prerequisite. The complete programs below use Java 17-compatible syntax.

Keys and current mappings

Map stores keys associated with values. A key identifies at most one current mapping, so putting the same key again replaces its old value.

put returns the previous value associated with the key, or null when no previous value existed. Because some maps permit null values, a null return alone may not distinguish absence from a previous null association. get has the same ambiguity, so containsKey answers whether a mapping exists. Do not use get(key) != null as a universal presence check when null values are allowed.

Hash, insertion and sorted order

HashMap does not promise iteration order. LinkedHashMap normally preserves insertion order, while TreeMap orders keys by natural order or a comparator.

HashMap uses equality and hashing and does not promise iteration order. LinkedHashMap preserves insertion order by default; a special constructor can select access order for designs such as caches. Updating an existing key in an insertion-ordered map does not move it to a new insertion position. TreeMap orders keys by natural order or a comparator, and comparison equality determines key identity for its ordering structure.

Missing values and stable map keys

get can return null for an absent key, and some maps also allow mapped null values. containsKey distinguishes those cases; getOrDefault provides a fallback only for an absent mapping.

Map keys should have stable equality and hash behavior while stored in a hash map, or stable ordering behavior in a sorted map. Changing a key's identifying fields can make an entry difficult to find or disrupt ordering. Prefer immutable keys such as strings or suitable records. Values can change without changing the key, provided the application's rules allow it.

Update operations, entry views and concurrency

merge and compute methods express updates without a separate lookup followed by put. Ordinary HashMap is not automatically safe for concurrent updates.

entrySet exposes a backed view of key-value entries and is efficient when both pieces are needed during iteration. keySet and values are also views, not detached copies. Supported removals through them affect the map. Maps are not automatically thread-safe; compound read-then-write operations can race when shared. Choose a concurrency contract deliberately rather than assuming ordinary put operations synchronize the whole workflow.

Running the examples

Save name.java, compile it with javac --release 17 name.java, and run java name. Use each program's own public class name and filename.

How ToolLoanMap produces its output

The map initially associates Rake with two and Spade with one. merge supplies one more for Rake and uses Integer.sum to combine the existing value with that addition, producing three. LinkedHashMap retains the key order. Hoe has no association, so getOrDefault supplies zero without inserting a Hoe entry into the map.

How UpdatedMapEntry produces its output

The first A association holds two. Replacing it with seven returns that old value and leaves two distinct keys. LinkedHashMap preserves A before B because updating a key does not create a new insertion position in the default mode. The map display shows the new value while its size remains two.

How MapPresence produces its output

HashMap allows a null value, so get(A) prints null even though A has a mapping. containsKey(A) establishes that association's presence, while containsKey(B) confirms B is missing. A get-only test would lose this distinction. Decide whether null is legitimate data before choosing a map API that permits it.

Choose a default without modifying the map

getOrDefault reads a mapping when present and otherwise returns its supplied fallback. It does not insert that fallback into the map. In contrast, computeIfAbsent can establish a non-null computed mapping for an absent or null-valued key. merge combines a supplied non-null value with an existing non-null value through its remapping function; a null remapping result removes the association. In the loan example, Integer.sum adds one to Rake's existing count, while reading Hoe with a default leaves the map unchanged. For practice, print containsKey before and after a defaulted read to confirm that lookup and insertion remain different operations.

How SortedMapKeys produces its output

TreeMap compares the String keys in natural order. Copper sorts before Zinc, so the display differs from insertion order. The associated quantities stay attached to their keys; the values nine and one do not control ordering. This is useful when a report requires predictable key order without a separate sorting step.

Java Summary

  • Map stores keys associated with values. A key identifies at most one current mapping, so putting the same key again replaces its old value.
  • HashMap does not promise iteration order. LinkedHashMap normally preserves insertion order, while TreeMap orders keys by natural order or a comparator.
  • get can return null for an absent key, and some maps also allow mapped null values. containsKey distinguishes those cases; getOrDefault provides a fallback only for an absent mapping.
  • merge and compute methods express updates without a separate lookup followed by put. Ordinary HashMap is not automatically safe for concurrent updates.
  • Continue with Java exercises, Java quizzes and the Java study roadmap.

Java Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Java HashMap, TreeMap and LinkedHashMap in a complete program

Java
public class ToolLoanMap  {
    public static void main(String[] args)  {
        java.util.Map<String,Integer> loans = new java.util.LinkedHashMap<>();
        loans.put("Rake", 2);
        loans.put("Spade", 1);
        loans.merge("Rake", 1, Integer::sum);
        System.out.println(loans);
        System.out.println(loans.getOrDefault("Hoe", 0));
    }
}
Output
{Rake=3, Spade=1}
0
Line-by-line explanation
  1. Line 7Evaluates loans and prints {Rake=3, Spade=1}.
  2. Line 8Evaluates loans.getOrDefault("Hoe", 0) and prints 0.
Example 2

An existing key replaces its value

Java
public class UpdatedMapEntry  {
    public static void main(String[] args)  {
        java.util.Map<String, Integer> seats = new java.util.LinkedHashMap<>();
        seats.put("A", 2);
        seats.put("B", 4);
        System.out.println(seats.put("A", 7));
        System.out.println(seats);
        System.out.println(seats.size());
    }
}
Output
2
{A=7, B=4}
2
Line-by-line explanation
  1. Line 6Evaluates seats.put("A", 7) and prints 2.
  2. Line 7Evaluates seats and prints {A=7, B=4}.
  3. Line 8Evaluates seats.size() and prints 2.
Example 3

Null and missing are distinct

Java
public class MapPresence  {
    public static void main(String[] args)  {
        java.util.Map<String, String> notes = new java.util.HashMap<>();
        notes.put("A", null);
        System.out.println(notes.get("A"));
        System.out.println(notes.containsKey("A"));
        System.out.println(notes.containsKey("B"));
    }
}
Output
null
true
false
Line-by-line explanation
  1. Line 5Evaluates notes.get("A") and prints null.
  2. Line 6Evaluates notes.containsKey("A") and prints true.
  3. Line 7Evaluates notes.containsKey("B") and prints false.
Example 4

TreeMap sorts keys rather than values

Java
public class SortedMapKeys {
    public static void main(String[] args) {
        java.util.Map<String, Integer> stock = new java.util.TreeMap<>();
        stock.put("Zinc", 1);
        stock.put("Copper", 9);
        System.out.println(stock);
    }
}
Output
{Copper=9, Zinc=1}
Line-by-line explanation
  1. Lines 3 to 5Creates a TreeMap and adds Zinc before Copper; key comparison determines the resulting order.
  2. Line 6Prints Copper before Zinc even though Copper was inserted later and has the larger value.

Java FAQ

Are duplicate values allowed?

Yes. Different keys can map to equal values, including the same referenced object. Uniqueness belongs to keys, not values. A value collection may therefore contain duplicates even though keySet is a set.

Does TreeMap preserve insertion order?

No. It presents keys in its natural or comparator order. LinkedHashMap is the usual choice for insertion-ordered traversal, while HashMap makes no ordering promise. Select the contract that matches how entries need to be displayed or searched.

What does computeIfAbsent do?

It returns the value for a key, creating and storing it first if the key is missing. It's the neat way to group items: map.computeIfAbsent(team, k -> new ArrayList<>()).add(player) creates each team's list the first time the team appears and then appends to it.

How do I find the smallest, largest or nearest key?

Use a TreeMap. firstKey() and lastKey() give the smallest and largest keys, floorKey(k) the greatest key at or below k, and ceilingKey(k) the smallest at or above it. headMap and tailMap return the entries below or above a key.

How can a LinkedHashMap work as a simple cache?

Create it with access order, new LinkedHashMap<>(16, 0.75f, true), so reading an entry moves it to the end, and override removeEldestEntry to return true when the size passes a limit. The least recently used entry is then removed automatically when a new one is added.

Java Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

What happens when put uses an existing key?

Multiple choicemedium

Which method distinguishes a null mapping from a missing key?

Java Quiz

2 questions to check what you learned.

  1. What determines TreeMap key order?

    • Natural order or its supplied comparator
    • Insertion order in all cases
    • Value hashes
  2. What does entrySet provide?

    • A backed view of key-value entries
    • A deep copy of every key and value
    • Only sorted values