HashSet
HashSet internals, when to use it over a List, and the equals/hashCode contract that makes or breaks it.
Last reviewed: January 2025
🔍 What Is It?
HashSet is java.util.Set backed by a HashMap<E, PRESENT> where PRESENT is a static dummy Object.
Key Characteristics:
- →No duplicates — add() returns false if element already present
- →No ordering — iteration order is unpredictable
- →O(1) average for add, remove, contains
- →Allows one null element
- →Not thread-safe
Relationship to HashMap:
// HashSet internally uses:
private transient HashMap<E, Object> map;
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
public boolean contains(Object o) {
return map.containsKey(o);
}🎯 Why Do We Need It?
HashSet provides O(1) contains() vs O(n) for List. When you need to check "is this element already seen?" thousands of times, HashSet is the right tool. It is also the natural data structure for sets of unique identifiers, tags, permissions, and visited nodes in graph algorithms.
🏗️ What Happens in Real Projects?
Common enterprise patterns:
// Deduplication
Set<String> processedIds = new HashSet<>();
for (Event event : events) {
if (processedIds.add(event.getId())) { // add returns false if duplicate
process(event);
}
}
// Permission checking
Set<String> userRoles = user.getRoles();
if (userRoles.contains("ADMIN")) { ... }
// Visited tracking in BFS/DFS
Set<String> visited = new HashSet<>();
Queue<String> queue = new ArrayDeque<>();⚙️ How It Works
HashSet delegates everything to its backing HashMap. add(e) calls map.put(e, PRESENT). contains(o) calls map.containsKey(o). The same hashCode/equals requirements and collision handling apply.
💻 Example
HashSet in Practice — Practical HashSet usage patterns.
🤔 Common Confusions
❓ Why is my HashSet allowing "duplicates"?
Your class does not override equals() and hashCode(). Without these, two objects with the same data are considered different (default Object identity comparison). HashSet uses equals() to check for duplicates and hashCode() to find the right bucket. Override both, or use records (Java 16+) which auto-generate them.
❓ What is the difference between HashSet and TreeSet?
HashSet: O(1) operations, no ordering, uses hashCode/equals. TreeSet: O(log n) operations, always sorted, uses compareTo/Comparator (not equals/hashCode). Use HashSet when you just need uniqueness and fast lookup. Use TreeSet when you need elements in sorted order or need range queries (headSet, tailSet, subSet).
🚨 Common Production Issues
Mutating objects stored in HashSet — changing a field used in hashCode() after adding to a HashSet makes the element unfindable. The element is in the wrong bucket.
Missing equals/hashCode — the most common HashSet bug. Always override both for custom classes.
✅ Best Practices
Always override equals() and hashCode() for objects stored in HashSet.
Use records (Java 16+) for value objects — they auto-generate equals/hashCode.
Use LinkedHashSet when you need deduplication with preserved insertion order.
Use EnumSet for sets of enum values — it is faster than HashSet.
Use Set.copyOf() to create an immutable copy of a HashSet.
🏛️ Architect's Note
In JPA/Hibernate, use Set<T> (not List<T>) for @ManyToMany and @OneToMany relationships when duplicates are not allowed. However, Hibernate has specific requirements for equals/hashCode in entities: base them on a natural business key (email, SKU) rather than the database-generated ID, because the ID is null before the entity is persisted.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
Core Java Interview Prep
Practice interview questions that connect directly to this technology track.
↗ Where this topic fits
Core Java Technology Guide
Return to the Core Java learning hub.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Core Java references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Core Java learning path
Browse the full Core Java topic collection and learning order on SplashRide.
Core Java Interview Prep
Practice Core Java interview questions and scenario-based answers.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Set
The Set interface — no duplicates, fast membership testing. HashSet, LinkedHashSet, TreeSet — when to use each.
HashMap
HashMap internals, hash collisions, load factor tuning, and why HashMap is the most important collection to understand deeply.