Back to Set: HashSet, LinkedHashSet, TreeSet
Q3Question 3 of 5

What is the difference between HashSet and LinkedHashSet?

Key Concepts
  • HashSet uses HashMap internally and has no ordering guarantee; iteration order is unpredictable and may change after resize
  • LinkedHashSet uses LinkedHashMap internally and maintains insertion order via a doubly-linked list across entries
  • Both provide O(1) average time for add, remove, and contains operations
  • LinkedHashSet uses slightly more memory per element (~8 extra bytes for two linked-list pointers)
  • LinkedHashSet iteration is faster than HashSet because it follows the linked list instead of scanning the bucket array
  • Use LinkedHashSet when deterministic iteration order matters for testing, auditing, or output consistency

Definition

HashSet is unordered with O(1) operations; LinkedHashSet adds insertion-order iteration at the cost of slightly more memory per element.
  • HashSet: backed by HashMap, no ordering guarantee, O(1) operations, iteration scans bucket array (may visit empty buckets)
  • LinkedHashSet: extends HashSet using LinkedHashMap, maintains a doubly-linked list across all entries for insertion order
  • Performance: both O(1) for add/contains/remove; LinkedHashSet iteration is slightly faster because it follows the linked list directly
  • Memory: LinkedHashSet uses ~8 extra bytes per entry for the before/after linked-list pointers
  • Null: both allow one null element

HashSet is like throwing unique cheques into a drawer – no duplicates, but you cannot predict the order you pull them out. LinkedHashSet is the same drawer with a thread tying the cheques together in the exact order you dropped them in, so you always read them back in arrival order.

Understanding the Concepts

What is the difference between HashSet and LinkedHashSet?

Both reject duplicates using hashCode() and equals(). The only difference is iteration order.

JAVA
package com.bank.demo;

import java.util.*;

public class HashSetVsLinkedHashSetDemo {
    public static void main(String[] args) {
        // HashSet: iteration order is unpredictable
        Set<String> hashSet = new HashSet<>();
        hashSet.add("SAV2001");
        hashSet.add("CUR3001");
        hashSet.add("FD4001");
        hashSet.add("LON5001");
        System.out.println("HashSet:       " + hashSet);

        // LinkedHashSet: iteration order = insertion order
        Set<String> linkedSet = new LinkedHashSet<>();
        linkedSet.add("SAV2001");
        linkedSet.add("CUR3001");
        linkedSet.add("FD4001");
        linkedSet.add("LON5001");
        System.out.println("LinkedHashSet: " + linkedSet);

        // Adding and removing does not change order for LinkedHashSet
        linkedSet.remove("CUR3001");
        linkedSet.add("CUR3001"); // re-added at the END
        System.out.println("After re-add:  " + linkedSet);
    }
}
TEXT
HashSet:       [FD4001, LON5001, CUR3001, SAV2001]
LinkedHashSet: [SAV2001, CUR3001, FD4001, LON5001]
After re-add:  [SAV2001, FD4001, LON5001, CUR3001]

Why does ordering matter?

Deterministic iteration order is important for:

  • Audit logs: statements must list accounts in a consistent, reproducible order.
  • Test assertions: unit tests that compare set contents fail intermittently with HashSet because iteration order varies between JVM runs.
  • API responses: JSON serialization of a set produces different output each time with HashSet.
  • Deduplication: when removing duplicates from a feed, LinkedHashSet preserves the first occurrence.
JAVA
package com.bank.service;

import java.util.*;

public class OrderingMattersDemo {
    public static void main(String[] args) {
        // Test assertion with HashSet: FRAGILE
        Set<String> hashResult = new HashSet<>(List.of("A", "B", "C"));
        // hashResult.toString() varies between runs!
        // assertEquals("[A, B, C]", hashResult.toString()); // may fail!

        // Test assertion with LinkedHashSet: DETERMINISTIC
        Set<String> linkedResult = new LinkedHashSet<>(List.of("A", "B", "C"));
        System.out.println(linkedResult.toString()); // always [A, B, C]

        // JSON output
        // {"accounts": ["SAV2001", "CUR3001"]} – always this order with LinkedHashSet
        // {"accounts": ["CUR3001", "SAV2001"]} – random with HashSet
    }
}
TEXT
[A, B, C]

What about iteration performance?

LinkedHashSet iterates faster than HashSet for sparse maps. HashSet's iterator scans the entire bucket array, skipping empty buckets. If the map has capacity 10,000 but only 100 entries, the iterator visits 10,000 slots. LinkedHashSet's iterator follows the linked list and visits exactly 100 entries.

For dense maps (many entries relative to capacity), the difference is negligible.

When should you use each?

| Scenario | Best choice |
|---|---|
| Fast membership testing, order irrelevant | HashSet |
| Membership testing + deterministic iteration | LinkedHashSet |
| Dedup preserving first occurrence | LinkedHashSet |
| Unit test assertions on set contents | LinkedHashSet |
| JSON serialization with consistent field order | LinkedHashSet |
| Memory-sensitive with many elements | HashSet |

What should a senior engineer know?

- LinkedHashSet does not support access-order mode. LinkedHashMap has an access-order mode (move-to-end on get), but LinkedHashSet does not expose it. For LRU cache behavior, use LinkedHashMap directly.

- Re-adding a removed element. If you remove and re-add an element in LinkedHashSet, it goes to the end of the insertion order (not back to its original position).

- Set.of() is unordered. Set.of("A", "B", "C") returns an immutable set with no ordering guarantee. It is not a LinkedHashSet.

What are common interview follow-up questions?

  • "Which Set preserves insertion order?" – LinkedHashSet.
  • "What is the memory overhead of LinkedHashSet vs HashSet?" – ~8 extra bytes per entry for the linked-list pointers.
  • "Is LinkedHashSet slower than HashSet?" – No, both are O(1); LinkedHashSet iteration is actually faster for sparse sets.

Visual Overview

TEXT
  HashSet (HashMap buckets):
  [0] [1] [2:SAV2001] [3] [4:CUR3001] ... [15:FD4001]
  Iteration: scans ALL buckets (including empty ones)

  LinkedHashSet (LinkedHashMap with linked list):
  [0] [1] [2:SAV2001] [3] [4:CUR3001] ... [15:FD4001]
       SAV2001 ↔ CUR3001 ↔ FD4001   (doubly-linked list)
  Iteration: follows the linked list (skips empty buckets)

Key Takeaway

HashSet and LinkedHashSet both provide O(1) uniqueness enforcement, but HashSet gives unpredictable iteration order while LinkedHashSet guarantees insertion order via a doubly-linked list across entries.

In the National Bank of India's reporting module, Rajesh uses HashSet when he only needs fast membership checks – like verifying whether an account is in the blocked list. He uses LinkedHashSet whenever the output order must be reproducible, such as listing the accounts in a batch in the exact order they were received, for audit compliance and deterministic test assertions.

The memory cost of LinkedHashSet is small – about 8 extra bytes per element for the two linked-list pointers. For most applications, this is a trivial cost for the benefit of predictable, reproducible iteration order.

Remember one sentence: LinkedHashSet is a HashSet that remembers insertion order – use it when iteration order matters for testing, auditing, or output consistency.

---

Share
Use ← → arrow keys to navigate