HashMap
Insertion Order
Java
Data Structures
Programming Tips

How to preserve insertion order in HashMap?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

In Java, HashMap does not preserve insertion order. If you put keys into a HashMap in one order and iterate later, the iteration order is unspecified and can change as the map grows or is rehashed.

If you need stable insertion order, the usual answer is not to force HashMap into behaving differently. It is to use LinkedHashMap, which is specifically designed to keep entries in insertion order while still offering hash-table lookup performance.

Why HashMap Does Not Preserve Order

HashMap is optimized around hashing and bucket storage, not around predictable iteration order. That means code like this should not be relied on for ordered output:

java
1import java.util.HashMap;
2import java.util.Map;
3
4public class Demo {
5    public static void main(String[] args) {
6        Map<Integer, String> map = new HashMap<>();
7        map.put(3, "three");
8        map.put(1, "one");
9        map.put(2, "two");
10
11        for (Map.Entry<Integer, String> entry : map.entrySet()) {
12            System.out.println(entry.getKey() + " = " + entry.getValue());
13        }
14    }
15}

The code compiles and runs, but the iteration order is not a contract. If your logic depends on insertion order, HashMap is the wrong data structure.

Use LinkedHashMap Instead

LinkedHashMap extends the hash-map idea with a linked structure that records iteration order. The simplest insertion-order version looks like this:

java
1import java.util.LinkedHashMap;
2import java.util.Map;
3
4public class Demo {
5    public static void main(String[] args) {
6        Map<Integer, String> map = new LinkedHashMap<>();
7        map.put(3, "three");
8        map.put(1, "one");
9        map.put(2, "two");
10
11        for (Map.Entry<Integer, String> entry : map.entrySet()) {
12            System.out.println(entry.getKey() + " = " + entry.getValue());
13        }
14    }
15}

This reliably prints the entries in the order they were inserted:

text
3 = three
1 = one
2 = two

That is the standard answer whenever people ask how to preserve insertion order in a hash-based map.

Understand Reinsertions and Access Order

There are two useful subtleties to know.

First, reinserting an existing key with put updates the value but does not create a second position in the order. The key keeps its original insertion slot.

Second, LinkedHashMap can also be configured for access order instead of insertion order. That is useful for cache-like behavior:

java
1import java.util.LinkedHashMap;
2import java.util.Map;
3
4public class Demo {
5    public static void main(String[] args) {
6        Map<Integer, String> map = new LinkedHashMap<>(16, 0.75f, true);
7        map.put(1, "one");
8        map.put(2, "two");
9        map.put(3, "three");
10
11        map.get(1);
12        map.get(2);
13
14        for (Map.Entry<Integer, String> entry : map.entrySet()) {
15            System.out.println(entry.getKey());
16        }
17    }
18}

With accessOrder=true, the order reflects recent access rather than original insertion. That is different from the question here, but it is an important feature of the same class.

Use It for More Than Pretty Iteration

Insertion order matters in several practical situations:

  • generating stable JSON or log output
  • preserving user-defined option order
  • building deterministic tests
  • keeping unique items in the order first seen

For example, if you want unique strings while preserving the order they first appeared:

java
1import java.util.LinkedHashMap;
2import java.util.Map;
3
4public class UniqueWords {
5    public static void main(String[] args) {
6        String[] words = {"apple", "pear", "apple", "banana"};
7        Map<String, Boolean> seen = new LinkedHashMap<>();
8
9        for (String word : words) {
10            seen.putIfAbsent(word, true);
11        }
12
13        System.out.println(seen.keySet());
14    }
15}

This prints the unique values in first-seen order.

Common Pitfalls

The most common mistake is assuming the current iteration order of a HashMap is stable just because it "looks right" in a test run. That behavior is not guaranteed.

Another common issue is choosing TreeMap when the real requirement is insertion order rather than sorted order. TreeMap sorts by key, which is a completely different behavior.

People also forget about the access-order constructor on LinkedHashMap and accidentally create cache-like iteration when they really wanted insertion order.

Finally, remember that preserving order has a small overhead. In most applications the tradeoff is worth it, but it is still a deliberate data-structure choice.

Summary

  • 'HashMap does not preserve insertion order.'
  • Use LinkedHashMap when insertion order matters.
  • Reinserting an existing key updates the value without creating a new position.
  • 'LinkedHashMap can also be configured for access order, which is different from insertion order.'
  • Pick the map type based on the order semantics your program actually needs.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.