HashSet in Java
HashSet is one of the most commonly used Set implementations in Java. It stores unique elements only, does not maintain order, and provides fast performance using hashing.
What is HashSet in Java?
A HashSet is a collection in Java that:
- Stores unique elements (no duplicates allowed)
- Does not maintain insertion order
- Allows only one null value
- Provides O(1) average-time performance for add, remove, and search
- Internally uses a HashMap
HashSet in Collection Hierarchy
Iterable
└── Collection
└── Set
└── HashSet
HashSet Implements
- Set
- Cloneable
- Serializable
Key Features of HashSet
- Unique elements only
- No duplicates
- No indexing (unlike List)
- Order is not guaranteed
- Allows one null value
- Very fast operations (hashing)
- Internally uses a HashMap
- Resizes automatically (rehashing)
Internal Working of HashSet
HashSet stores data as keys inside a HashMap.
When you add an element:
hash = hashCode(element)
bucket = hash % array_length
store element in that bucket
Internal Structure Diagram
Hash Table (Buckets)
0 → [Apple]
1 → [null]
2 → [Banana → Grapes]
3 → [null]
4 → [Orange]
What Happens During Collision?
If two elements have the same hash bucket:
- They are stored in a linked list
- After Java 8, if chain length > 8 → converted into a Red-Black Tree → O(log n)
How Elements Are Stored Internally?
Each element becomes a key in HashMap:
K = element
V = dummy value (PRESENT)
When to Use HashSet?
Use HashSet when you need:
- Unique values
- Fast searching (contains)
- Fast insertion/removal
- A lightweight, fast Set
- No concern about order
Avoid HashSet if:
- Order matters → Use LinkedHashSet
- Sorting required → Use TreeSet
Constructors of HashSet
HashSet provides multiple constructors to create a new set:

Default Constructor
Creates an empty HashSet with default capacity and load factor.
HashSet<String> set = new HashSet<>();
With Initial Capacity
Creates an empty HashSet with a specified initial capacity.
HashSet<Integer> set = new HashSet<>(50);
With Initial Capacity + Load Factor
Allows specifying both initial capacity and load factor for performance tuning.
HashSet<String> set = new HashSet<>(32, 0.75f);
Create from Another Collection
Initializes a HashSet with elements from an existing collection, automatically removing duplicates.
HashSet<String> set = new HashSet<>(list);
Common HashSet Methods

1. Add Methods
add(E e)
Adds the element to the set if it is not already present; duplicates are ignored.
set.add("HTML");
2. Search/Check Methods
contains(Object o)
Checks if the specified element exists in the set; returns true or false.
set.contains("Java");
3. Remove Methods
remove(Object o)
Removes the element from the set if it exists; returns true if removal was successful.
set.remove("Python");
clear()
Removes all elements from the HashSet, making it empty.
set.clear();
4. Utility Methods
size()
Returns the total number of elements currently stored in the set.
set.size(); // total elements
isEmpty()
Checks whether the set contains no elements.
set.isEmpty();
iterator()
Returns an iterator to traverse all elements of the set one by one.
set.iterator();
5. Bulk Operations
addAll(Collection<? extends E> c)
Adds all elements from another collection into this set (duplicate elements ignored).
set1.addAll(set2); // union
removeAll(Collection<?> c)
Removes all elements from this set that are also present in the given collection.
set1.removeAll(set2); // difference
retainAll(Collection<?> c)
Keeps only the elements that are common between this set and the given collection.
set1.retainAll(set2); // intersection
Time Complexity of HashSet
| Operation | Time Complexity | Explanation |
|---|---|---|
| add() | O(1) average | Hashing-based |
| remove() | O(1) average | Direct bucket removal |
| contains() | O(1) average | Hash lookup |
| iterate() | O(n) | Visit all elements |
| worst-case | O(n) or O(log n with tree) | Collision-heavy buckets |
HashSet vs ArrayList vs LinkedList
| Feature | HashSet | ArrayList | LinkedList |
|---|---|---|---|
| Duplicate Allowed | No | Yes | Yes |
| Order | No | Yes | Yes |
| Searching | Fast (O(1)) | Medium | Slow |
| Indexing | No | Yes | No |
| Structure | Hash Table | Dynamic Array | Doubly Linked List |
Advantages of HashSet
- Very fast add/remove/search (O(1))
- Ensures uniqueness
- Efficient for large datasets
- Good for lookup operations
- Allows one null value
- Simple & memory-efficient
Disadvantages of HashSet
- No ordering
- No indexing
- Performance depends on good hashCode()
- Worst-case may degrade to O(n)
Real-World Use Cases of HashSet
- Removing duplicate entries
- Unique product IDs / emails
- Membership testing
- Caching systems
- Fast lookup-based operations
- Detecting duplicate words in text
- Maintaining unique visitors in an app
HashSet Example
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // duplicate → ignored
System.out.println(set);
}
}
HashSet Example (Iteration)
for (String s : set) {
System.out.println(s);
}
Example: Removing Duplicates from a List
List<Integer> list = Arrays.asList(10, 20, 10, 30, 20);
HashSet<Integer> unique = new HashSet<>(list);
System.out.println(unique);
Load Factor & Rehashing
Default load factor = 0.75
When:
size > capacity × loadFactor
→ HashSet resizes (rehashing happens)
Rehashing is expensive (O(n)) but rare.
Points to Remember
- HashSet = fast, unique, unordered collection
- Internally uses HashMap
- Average performance: O(1)
- Great for unique elements, searching, duplicate removal
- If you need order → use LinkedHashSet
- If you need sorted order → use TreeSet
