Difference Between LinkedHashSet and TreeSet in Java
LinkedHashSet and TreeSet are both Set implementations with a predictable iteration order, but the order means different things:
LinkedHashSetkeeps elements in insertion order, using a hash table plus a linked list. Operations are O(1).TreeSetkeeps elements sorted (natural order or aComparator), using a red-black tree. Operations are O(log n), and it offers navigation methods such asfirst,ceilingandheadSet.
1. Comparison Table
| Aspect | LinkedHashSet | TreeSet |
|---|---|---|
| Order | Insertion order | Sorted (ascending, or by comparator) |
| Internal structure | LinkedHashMap (hash table + doubly linked list) | TreeMap (red-black tree) |
| add / remove / contains | O(1) average | O(log n) |
| Duplicate detection | hashCode() + equals() | compareTo() or compare() |
| Null | One null allowed | Not allowed (with natural ordering) |
| Element requirement | Any object | Must be Comparable, or supply a Comparator |
| Interfaces | SequencedSet | NavigableSet, SortedSet, SequencedSet |
| Range / navigation | No | first, last, floor, ceiling, headSet, subSet… |
| Thread-safe | No | No (ConcurrentSkipListSet is the concurrent sorted set) |
2. Insertion Order vs Sorted Order
import java.util.*;
public class OrderingDemo {
public static void main(String[] args) {
List<Integer> scores = List.of(72, 95, 61, 88, 95, 40, 72);
Set<Integer> linked = new LinkedHashSet<>(scores);
TreeSet<Integer> tree = new TreeSet<>(scores);
System.out.println("LinkedHashSet : " + linked + " (insertion order)");
System.out.println("TreeSet : " + tree + " (sorted)");
// Navigation methods: only TreeSet
System.out.println("first / last : " + tree.first() + " / " + tree.last());
System.out.println("ceiling(80) : " + tree.ceiling(80) + ", floor(80): " + tree.floor(80));
System.out.println("headSet(72) : " + tree.headSet(72) + ", tailSet(72): " + tree.tailSet(72));
System.out.println("descendingSet : " + tree.descendingSet());
// Custom ordering with a Comparator
TreeSet<String> names = new TreeSet<>(Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder()));
names.addAll(List.of("Ravi", "Asha", "Meera", "Jo", "Kiran"));
System.out.println("by length : " + names);
}
}
LinkedHashSet : [72, 95, 61, 88, 40] (insertion order) TreeSet : [40, 61, 72, 88, 95] (sorted) first / last : 40 / 95 ceiling(80) : 88, floor(80): 72 headSet(72) : [40, 61], tailSet(72): [72, 88, 95] descendingSet : [95, 88, 72, 61, 40] by length : [Jo, Asha, Ravi, Kiran, Meera]
Only TreeSet can answer questions such as "the smallest score at least 80" (ceiling) or "all scores below 72" (headSet) efficiently.
3. Nulls, Comparable and compareTo
import java.util.*;
public class NullAndCompare {
record Item(String name) { } // not Comparable
public static void main(String[] args) {
Set<String> linked = new LinkedHashSet<>();
linked.add(null);
System.out.println("LinkedHashSet accepts null: " + linked.contains(null));
try {
new TreeSet<String>().add(null);
} catch (NullPointerException e) {
System.out.println("TreeSet.add(null): NullPointerException");
}
try {
new TreeSet<Item>().add(new Item("pen"));
} catch (ClassCastException e) {
System.out.println("TreeSet of non-Comparable: ClassCastException");
}
// TreeSet uses compareTo, not equals, to detect duplicates
TreeSet<String> ci = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
ci.addAll(List.of("Java", "JAVA", "java"));
System.out.println("case-insensitive TreeSet: " + ci);
}
}
LinkedHashSet accepts null: true TreeSet.add(null): NullPointerException TreeSet of non-Comparable: ClassCastException case-insensitive TreeSet: [Java]
TreeSetmust compare elements, sonulland non-Comparableobjects fail without a suitable comparator.- It treats elements as duplicates when
compareToreturns 0, even ifequalssays otherwise. Keep comparators consistent withequalsunless that is what you intend.
4. When to Use Which
LinkedHashSet: unique elements in the order they arrived, with the fastest operations (de-duplicating input, recent unique items).TreeSet: unique elements kept sorted, or when you need range queries and nearest-element lookups (leaderboards, schedules, price bands).- If you only need sorted output occasionally, a
HashSetplus sorting at the end can be cheaper than maintaining aTreeSet.
5. Summary
LinkedHashSet: insertion order, O(1), one null allowed, usesequals/hashCode.TreeSet: sorted order, O(log n), no null, usescompareTo/comparator.- Only
TreeSetprovides navigation and range views. - Neither is thread-safe.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is the main difference between LinkedHashSet and TreeSet?
LinkedHashSet keeps insertion order; TreeSet keeps elements sorted.
Q2. Which is faster?
LinkedHashSet, with O(1) average operations, compared with O(log n) for TreeSet.
Q3. Can TreeSet store null?
No, not with natural ordering; it throws NullPointerException. A custom comparator could handle nulls, but this is rarely wise.
Q4. Can LinkedHashSet store null?
Yes, one null element.
Q5. What data structure does TreeSet use?
A red-black tree, through an internal TreeMap.
Q6. What data structure does LinkedHashSet use?
A hash table with a doubly linked list running through the entries, via LinkedHashMap.
Q7. Why do I get ClassCastException with TreeSet?
The elements do not implement Comparable and no comparator was provided.
Q8. How does TreeSet detect duplicates?
By compareTo (or the comparator) returning 0, not by equals.
Q9. How do I sort a TreeSet in descending order?
Use new TreeSet<>(Comparator.reverseOrder()) or treeSet.descendingSet().
Q10. Which methods does TreeSet have that LinkedHashSet lacks?
Navigation and range methods: floor, ceiling, higher, lower, headSet, tailSet, subSet, pollFirst, pollLast.
Q11. Do both implement SequencedSet?
Yes, since Java 21, but TreeSet does not support addFirst/addLast because its order is determined by sorting.
Q12. Are they thread-safe?
No. Use ConcurrentSkipListSet for a concurrent sorted set, or synchronized wrappers.
Q13. Which uses more memory?
Both have per-entry overhead; tree nodes hold parent, left, right references and a colour flag, while linked hash entries hold hash, next, before and after references. They are comparable.
Q14. Can I convert one to the other?
Yes: new TreeSet<>(linkedHashSet) sorts the elements; new LinkedHashSet<>(treeSet) keeps the sorted order as insertion order.
Q15. Is TreeSet good for frequent insertions?
It is fine, at O(log n) each. If you only need sorting at the end, collecting in a list or hash set and sorting once is faster.
Q16. Do both allow duplicates?
No. Both are sets.
Q17. Are their iterators fail-fast?
Yes, both throw ConcurrentModificationException on concurrent structural modification.
Q18. Which interface gives sorted behaviour?
SortedSet and its extension NavigableSet, both implemented by TreeSet.
Q19. Can TreeSet use a custom order?
Yes, by passing a Comparator to the constructor, such as ordering strings by length.
Q20. When would HashSet be better than both?
When order does not matter at all: it is the simplest and slightly fastest choice.