Difference between HashSet, LinkedHashSet, and TreeSet —… — Cracked Java
// Java Collections Framework · Set, HashSet, LinkedHashSet, TreeSet
JuniorTheoryEPAM

Difference between HashSet, LinkedHashSet, and TreeSet — when to use each?

HashSet is fastest with no ordering, LinkedHashSet preserves insertion order at a small cost, and TreeSet keeps elements sorted at the cost of O(log n) operations. Pick based on which property you actually need — defaulting to HashSet is almost always right.

Side-by-Side

AspectHashSetLinkedHashSetTreeSet
Backing structureHashMapLinkedHashMap (hash + linked list)TreeMap (red-black tree)
Iteration orderUnspecified, may changeInsertion orderSorted (Comparable / Comparator)
add/remove/containsO(1) average, O(log n) worst (treeified)O(1) averageO(log n)
Allows nullYes, oneYes, oneNo (NPE — can't compare null)
Element requirementSane equals/hashCodeSane equals/hashCodeComparable or supplied Comparator
Memory per element~32–48 bytes (node)+16 bytes (two extra references)~40+ bytes (tree node with parent/left/right + color)
ImplementsSetSet (insertion-ordered)NavigableSet, SortedSet
Reverse iterationNoNo (manual)YesdescendingSet
Range queriesNoNoYessubSet, headSet, tailSet
Thread-safeNoNoNo (ConcurrentSkipListSet exists)

Quick Code

Set<String> hs = new HashSet<>();
hs.add("c"); hs.add("a"); hs.add("b");
// Iteration order: unspecified — could be [a, b, c] or [c, a, b] or anything.

Set<String> lhs = new LinkedHashSet<>();
lhs.add("c"); lhs.add("a"); lhs.add("b");
// Iteration: [c, a, b]  — insertion order

NavigableSet<String> ts = new TreeSet<>();
ts.add("c"); ts.add("a"); ts.add("b");
// Iteration: [a, b, c]  — sorted

ts.first();           // "a"
ts.ceiling("b");      // "b"
ts.higher("b");       // "c"
ts.subSet("a", "c");  // [a, b]
ts.descendingSet();   // [c, b, a]

When to Choose Which

  • Default to HashSet. If you just need "membership test, no duplicates, fast" — done.
  • LinkedHashSet when iteration order must be predictable and stable (e.g., deduplicating while preserving insertion order, or building a deterministic test fixture).
  • TreeSet when you need sorted iteration, range queries (subSet), or nearest-neighbor lookups (floor/ceiling). Also when your elements have a natural ordering you want to leverage (scheduling, leaderboards).
  • EnumSet when the elements are an enum type — orders of magnitude faster than the others.

Subtle TreeSet Gotcha

TreeSet uses compareTo (or the Comparator) to determine equality, not equals. If your comparator returns 0 for two objects that are not equals, the set treats them as equal. This is a famous source of "I added two distinct objects and only one is there" bugs.

NavigableSet<String> ci = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
ci.add("Hello");
ci.add("HELLO");
System.out.println(ci.size());  // 1 — comparator says they're equal

Mark your status