LinkedHashSet
Overview
In Java’s collection framework, LinkedHashSet offers a blend of two desirable properties: uniqueness and insertion order preservation. It implements the Set interface and extends HashSet, but its backing store is a LinkedHashMap. This design gives it the constant‑time performance of a hash table while maintaining a predictable iteration order that matches the sequence in which elements were added.
Core Characteristics
- Uniqueness – Elements are considered duplicates if
equals()returnstrueand theirhashCode()values match. Only the first occurrence is kept. - Insertion Order – Iteration follows the order in which elements were inserted, unless an element is removed and re‑added.
- Null Support – One
nullvalue is allowed, just likeHashSet. - Performance –
add,remove, andcontainsrun in average O(1) time, slightly slower than a plainHashSetdue to the extra linkage maintenance. - Thread Safety – Not synchronized. Concurrent modifications require external synchronization.
- Fail‑Fast Iteration – Modifying the set while iterating (except via the iterator’s own
remove) throwsConcurrentModificationException.
Internal Mechanics
LinkedHashSet inherits almost all behavior from HashSet. Internally, it holds a single LinkedHashMap instance:
private transient HashMap<E,Object> map;
Each element added to the set becomes a key in this map; the value is a constant dummy object. LinkedHashMap augments the standard hash table with a doubly‑linked list that records the order of insertion. Consequently, operations that rely on the map’s hash table (like lookup) remain fast, while the list guarantees order.
Because LinkedHashSet extends HashSet, most methods simply delegate to the underlying map. The only difference is the constructor, which creates a LinkedHashMap instead of a plain HashMap.
Constructors
| Constructor | Description |
|---|---|
LinkedHashSet() |
Default capacity 16, load factor 0.75. |
LinkedHashSet(int initialCapacity) |
Sets the initial capacity. |
LinkedHashSet(int initialCapacity, float loadFactor) |
Sets both capacity and load factor. |
LinkedHashSet(Collection<? extends E> c) |
Builds a set containing all elements of the given collection, preserving that collection’s iteration order. |
These constructors let you tune memory usage and performance for large or predictable workloads.
Practical Example
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // duplicate – ignored
set.add("C++");
set.add(null);
System.out.println(set); // [Java, Python, C++, null]
System.out.println(set.contains("Python")); // true
System.out.println(set.size()); // 4
set.remove("C++");
for (String item : set) {
System.out.println(item);
}
}
}
Output:
[Java, Python, C++, null]
true
4
Java
Python
null
Notice that the duplicate "Java" is discarded and the iteration order matches the insertion sequence.
Comparison with Other Set Implementations
| Implementation | Order Guarantee | Typical Complexity | Null Allowed | Sorting |
|---|---|---|---|---|
HashSet |
No order | O(1) | Yes (one null) | No |
LinkedHashSet |
Insertion order | O(1) (slightly slower) | Yes (one null) | No |
TreeSet |
Natural or comparator order | O(log n) | Usually no | Yes |
- When to use
HashSet– If you only need fast uniqueness checks and don’t care about order. - When to use
TreeSet– If you require elements to be sorted automatically. - When to use
LinkedHashSet– When you need both uniqueness and a stable iteration order that reflects insertion.
Typical Use Cases
Removing Duplicates While Preserving Order
Convert aListto aLinkedHashSetto drop duplicates but keep the first occurrence’s position.Configuration and Menu Items
Store options or UI elements that must appear in the order they were defined.Path Tracking
Record unique nodes visited by a user or algorithm, maintaining the sequence of visits.Deterministic Serialization
Ensure that the order of elements in a serialized form is predictable for testing or caching.
Important Considerations
- Thread Safety – Wrap the set with
Collections.synchronizedSet(new LinkedHashSet<>())for concurrent access, but remember to synchronize manually during iteration. - Fail‑Fast Behavior – Use the iterator’s
remove()method if you need to delete elements while looping. - Correct
equals()/hashCode()– The set’s ability to detect duplicates depends entirely on these methods. - Access Order vs. Insertion Order –
LinkedHashSetpreserves insertion order. To maintain access order, use aLinkedHashMapwith access‑order enabled and build a set from it. - Memory Footprint – The linked list adds overhead; if order is unnecessary, prefer
HashSet.
Takeaway
LinkedHashSet is a practical choice when you need a unique collection that also respects the order of insertion. Its implementation via LinkedHashMap gives it near‑hash‑table speed while delivering predictable iteration. Understanding its trade‑offs—slightly higher memory usage, lack of built‑in thread safety, and the need for proper equals/hashCode—helps you decide when it’s the right tool for the job.