Java Set Explained (HashSet vs LinkedHashSet vs TreeSet)
-
Jason Yang - 22 Mar, 2026
- Updated 22 Mar, 2026
- Views —
And How It Compares to Python
If you’ve worked with Java for a while, you’ve probably used a Set to remove duplicates.
But when you actually sit down to write code, a common question comes up:
Should I use
HashSet,LinkedHashSet, orTreeSet?
They may look similar at first glance, but they behave quite differently under the hood.
Understanding those differences helps you make better decisions in real-world code.
Set (Interface)
Set is not a class — it’s an interface that defines the contract for all Set implementations.
The key rule is simple:
- No duplicate elements allowed
- At most one
nullis permitted (depending on the implementation)
You don’t create a Set directly.
Instead, you use one of its implementations like HashSet, LinkedHashSet, or TreeSet.
How Set Detects Duplicates
One important thing to keep in mind:
A Set does not determine duplicates by simple value comparison.
It relies on:
hashCode()equals()
If these are not implemented correctly, a Set may allow what looks like duplicate data.
For example, two objects with identical fields can still be treated as different if equals() and hashCode() are not overridden properly.
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Main {
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
set.add(new Person("Alice", 30));
set.add(new Person("Alice", 30)); // 같은 데이터
System.out.println(set.size());
}
}
HashSet (Default Choice)
This is the one you’ll use most of the time.
- Internal structure: Hash table (backed by
HashMap) - Order: Not guaranteed
- Performance:
- Average: O(1)
- Worst case: O(n) (due to hash collisions)
Use HashSet when:
- Order doesn’t matter
- You want the best performance for insert, lookup, and delete
LinkedHashSet (When Order Matters)
Think of it as a HashSet that also keeps track of insertion order.
- Internal structure: Hash table + linked list
- Order: Preserves insertion order
- Performance: Slightly slower than
HashSet, but still O(1) on average
Use LinkedHashSet when:
- You need uniqueness
- You also need to keep the original order
Typical examples:
- Recent search history
- Deduplicated lists that still need to be displayed in order
TreeSet (Always Sorted)
TreeSet keeps elements sorted at all times.
- Internal structure: Red-Black Tree
- Order: Sorted (natural order or custom comparator)
- Performance: O(log n)
A few things to keep in mind:
- Elements must be comparable
- Either implement
Comparable - Or provide a
Comparator
- Either implement
nullis not allowed (because elements must be compared)
Use TreeSet when:
- You need data to stay sorted
- You need range-based operations (e.g., values between 10 and 50)
Quick Comparison
| Java | Python Equivalent | Notes |
|---|---|---|
| HashSet | set | Default, fast, unordered |
| LinkedHashSet | (No direct equivalent) | Use dict (Python 3.7+) |
| TreeSet | (No direct equivalent) | Use sorted() or libraries |
| — | frozenset | Immutable set (Python only) |
Which One Should You Use?
A simple rule of thumb:
- Start with
HashSet - Switch to
LinkedHashSetif order becomes important - Use
TreeSetif you need sorted data or range queries
Java vs Python: A Different Approach
Java encourages you to choose the right data structure upfront.
Python takes a more flexible approach:
- Start simple
- Adjust only when necessary
Mapping Java to Python
| Java | Python Equivalent | Notes |
|---|---|---|
| HashSet | set | Default, fast, unordered |
| LinkedHashSet | (No direct equivalent) | Use dict (Python 3.7+) |
| TreeSet | (No direct equivalent) | Use sorted() or libraries |
| — | frozenset | Immutable set (Python only) |
① HashSet ↔ Python set
Python’s set is very similar to HashSet.
my_set = {1, 2, 3}
- Based on hashing
- Very fast
- Does not guarantee order
The order may look stable in some cases, but it’s not something you can rely on.
② LinkedHashSet ↔ Using dict
Python doesn’t have a built-in ordered set.
However, since Python 3.7, dict preserves insertion order.
That makes it a simple way to mimic LinkedHashSet.
my_list = [3, 1, 2, 2, 1]
ordered = list(dict.fromkeys(my_list))
print(ordered) # [3, 1, 2]
- Removes duplicates
- Preserves order
③ TreeSet ↔ Using sorted()
Python doesn’t keep data sorted automatically.
Instead, it sorts when needed:
sorted_values = sorted(my_set)
There’s an important difference here:
- Java
TreeSet→ Always sorted (O(log n) per insert) - Python
sorted()→ Sorts when called (O(n log n))
If you need frequent sorting, this difference can matter.
Advanced Note: bisect
If you want to maintain a sorted structure in Python:
- The
bisectmodule helps find insertion points using binary search - But inserting into a list is still O(n)
For large datasets, you may want to look into external libraries like sortedcontainers.
Python-Only Feature: frozenset
Python also provides frozenset, which Java doesn’t have.
fs = frozenset([1, 2, 3])
- Immutable (cannot be modified)
- Hashable
- Can be used as:
- Dictionary keys
- Elements inside another set
Final Thoughts
Java and Python solve the same problem in slightly different ways.
- Java gives you more control by offering multiple specialized implementations
- Python keeps things simple and lets you adapt when needed
Understanding both approaches makes it easier to choose the right tool depending on the situation.