Sets: HashSet & TreeSet
Unique elements with HashSet, LinkedHashSet and TreeSet, set algebra and navigation.
A set is a collection with no duplicates. Ask it "do you contain this?" and a hash-based set answers almost instantly, however large it is. Use sets for unique visitors, tags, permissions, already-seen IDs, and any time you would otherwise write if (!list.contains(x)) list.add(x).
HashSet basics#
add, remove and contains are all O(1) on average for a HashSet. A List needs O(n) for contains.
A
HashSethas no defined order. Elements may come out in any order, and that order can change as the set grows. Never rely on it.
Removing duplicates#
The three main implementations#
Set algebra: union, intersection, difference#
The bulk methods mutate the set they are called on, so copy first if you want to keep the original:
Set.of(...) creates an unmodifiable set (and throws if you pass duplicates or null).
TreeSet: sorted and navigable#
TreeSet is backed by a red-black tree. Besides keeping order, it implements NavigableSet, which answers "nearest" and "range" questions:
You can also give a TreeSet a custom order:
Important: a TreeSet decides equality using compareTo/the comparator, not equals. If the comparator says two elements are equal (returns 0), the second one is treated as a duplicate.
Sets of your own objects#
HashSet relies on hashCode() and equals() to detect duplicates. If your class doesn't override them, two objects with identical data are considered different:
The fix is to implement equals and hashCode, or use a record. This is covered in depth in the equals() & hashCode() lesson. Also, never mutate an object while it is inside a HashSet in a way that changes its hash code; the set will no longer find it.
Performance: List vs Set lookups#
Typical output (exact numbers depend on your machine):
50,000 lookups in a list of 50,000 is about 1.25 billion comparisons; the set does about 50,000 hash lookups.
Common mistakes#
- Relying on
HashSetiteration order. - Putting objects without
equals/hashCodeinto aHashSet. - Mutating elements after adding them to a hash-based set.
- Expecting
TreeSetto useequals; it uses the comparator. - Adding
nullto aTreeSetor toSet.of(...), which throwsNullPointerException.
What's next#
Sets store unique values. Often you need to associate values with keys instead: a phone book, word counts, a cache. That's the job of maps, up next.
Check your understanding
Quick quiz
1.What does
set.add("x")return if"x"is already in the set?2.You need unique elements kept in sorted order. Which implementation fits?
3.How does
retainAllchangeaina.retainAll(b)?
Finished reading?
Mark this lesson complete to track your progress.