Suppose you have a list of numbers:
10, 20, 30, 20, 40, 10You want to store only the unique values.
The result should be:
10, 20, 30, 40This is exactly the kind of problem a HashSet is designed to solve.
A HashSet is a collection that stores unique elements and uses hashing to provide fast operations such as insertion and searching.
What is a HashSet?
A HashSet stores individual values rather than key-value pairs.
For example:
10
20
30
40Unlike a HashMap, there is no separate key and value.
The value itself is what the set stores.
The most important property of a HashSet is:
It does not allow duplicate elements.
For example:
import java.util.HashSet;
HashSet<Integer> numbers = new HashSet<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(20);The value 20 was added twice, but the set contains it only once.
[10, 20, 30]Creating a HashSet
We can create a HashSet like this:
HashSet<Integer> numbers = new HashSet<>();Here:
Integer → Type of elements stored in the setWe can also create a set of strings:
HashSet<String> names = new HashSet<>();Now it can store:
John
Jason
Alex
MichaelAdding Elements
We use the add() method:
numbers.add(10);
numbers.add(20);
numbers.add(30);The set becomes:
10
20
30If we add 20 again:
numbers.add(20);nothing changes because 20 is already present.
Checking Whether an Element Exists
One of the most useful operations is:
contains()For example:
if (numbers.contains(20)) {
System.out.println("20 exists");
}Output:
20 existsHashSet is particularly useful when you need to quickly answer:
"Have I already seen this value?"
Removing an Element
We can remove an element using remove():
numbers.remove(20);If the set was:
10
20
30it becomes:
10
30Finding the Size
We can use:
numbers.size()For example:
System.out.println(numbers.size());If the set contains:
10
20
30the output is:
3Checking Whether It Is Empty
Use:
numbers.isEmpty()For example:
if (numbers.isEmpty()) {
System.out.println("Set is empty");
}Iterating Through a HashSet
We can use an enhanced for loop:
for (int number : numbers) {
System.out.println(number);
}For example, if the set contains:
10
20
30the loop processes each unique element.
Remember that the iteration order of a normal HashSet is not guaranteed.
So you should not rely on elements appearing in insertion order.
HashSet Does Not Allow Duplicates
This is the most important property of a HashSet.
Consider:
HashSet<String> names = new HashSet<>();
names.add("John");
names.add("Jason");
names.add("John");
names.add("Alex");
names.add("Jason");The final set contains only:
John
Jason
AlexThe duplicates are automatically ignored.
This makes HashSet extremely useful for removing duplicates.
Removing Duplicates from an Array
Suppose we have:
[10, 20, 10, 30, 20, 40]We can use a HashSet:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
int[] numbers = {
10, 20, 10, 30, 20, 40
};
HashSet<Integer> unique = new HashSet<>();
for (int number : numbers) {
unique.add(number);
}
System.out.println(unique);
}
}The result contains only unique values:
[10, 20, 30, 40]The order may differ because HashSet does not guarantee insertion order.
Finding Duplicate Elements
HashSet is also useful for detecting duplicates.
Suppose:
10, 20, 30, 20, 40We can keep track of values we've already seen:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
int[] numbers = {
10, 20, 30, 20, 40
};
HashSet<Integer> seen = new HashSet<>();
for (int number : numbers) {
if (seen.contains(number)) {
System.out.println(
"Duplicate: " + number
);
}
seen.add(number);
}
}
}Output:
Duplicate: 20The logic is simple:
Have we seen this number?
↓
Yes → Duplicate
↓
No
↓
Add it to HashSetThis pattern appears frequently in DSA.
HashSet for Checking Unique Characters
Suppose we want to determine whether every character in a string is unique.
For example:
"abcd"contains no duplicate characters.
We can use a HashSet:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
String text = "abcd";
HashSet<Character> seen = new HashSet<>();
boolean unique = true;
for (char ch : text.toCharArray()) {
if (seen.contains(ch)) {
unique = false;
break;
}
seen.add(ch);
}
System.out.println(unique);
}
}Output:
trueIf the string were:
"hello"the second l would already exist in the set, so the result would be false.
HashSet for Array Intersection
HashSet can also help us find common elements between two arrays.
Suppose:
Array 1: [1, 2, 3, 4]
Array 2: [3, 4, 5, 6]The common elements are:
3, 4We can store the first array in a HashSet:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
int[] first = {1, 2, 3, 4};
int[] second = {3, 4, 5, 6};
HashSet<Integer> set = new HashSet<>();
for (int number : first) {
set.add(number);
}
for (int number : second) {
if (set.contains(number)) {
System.out.println(number);
}
}
}
}Output:
3
4The HashSet lets us check whether each element from the second array exists in the first array efficiently.
HashSet and Hashing
HashSet uses hashing internally.
The basic idea is:
Element
↓
hashCode()
↓
Hash calculation
↓
BucketWhen we call:
set.add(20);Java uses the object's hash information to determine where it should be stored.
Later, when we call:
set.contains(20);the hash information helps Java quickly locate the appropriate area.
Hash Collisions
Different objects can sometimes produce the same hash location.
For example:
Value A → Bucket 3
Value B → Bucket 3This is called a hash collision.
A HashSet handles collisions internally.
You don't normally need to manually manage them when using Java's HashSet, but understanding collisions is important for understanding how hash-based data structures work.
Time Complexity
For a well-distributed HashSet, common operations are generally O(1) on average.
Operation | Average | Worst Case |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
*The exact worst-case behavior depends on the implementation and collision structure.
For DSA, the important point is:
add() → O(1) average
contains() → O(1) average
remove() → O(1) averageHashSet vs ArrayList
Both can store multiple elements, but they are designed for different purposes.
Feature | ArrayList | HashSet |
|---|---|---|
Allows duplicates | Yes | No |
Maintains insertion order | Yes | No guarantee |
Index-based access | Yes | No |
Fast lookup by value |
|
|
Allows | Yes | Yes, one |
For example, if you need:
[10, 20, 30, 20]and want to preserve the duplicate 20, use an ArrayList.
If you want:
10, 20, 30with unique values and fast membership checks, a HashSet is often a better choice.
HashSet vs HashMap
The difference is very important.
A HashSet stores:
ValueFor example:
10
20
30A HashMap stores:
Key → ValueFor example:
101 → John
102 → Jason
103 → AlexSo:
HashSet → Unique values
HashMap → Key-value pairsA Real-Life Example
Imagine a guest list for a party.
You receive names from different sources:
John
Jason
John
Alex
Jason
MichaelYou don't want to invite the same person twice.
You can use a HashSet:
John
Jason
Alex
MichaelEvery name is stored only once.
This is exactly the kind of problem where a HashSet is useful.
A Complete Example
Let's create a simple program that finds duplicate names:
import java.util.HashSet;
class Main {
public static void main(String[] args) {
String[] names = {
"John",
"Jason",
"Alex",
"John",
"Michael",
"Jason"
};
HashSet<String> seen = new HashSet<>();
for (String name : names) {
if (seen.contains(name)) {
System.out.println(
"Duplicate: " + name
);
} else {
seen.add(name);
}
}
}
}Output:
Duplicate: John
Duplicate: JasonThe HashSet remembers every name we've already encountered.
When we see a name again, contains() tells us that it already exists.
When Should You Use HashSet?
HashSet is particularly useful when you need to:
Store only unique elements
Remove duplicates
Quickly check whether an element exists
Detect duplicate values
Track elements you've already seen
Find common elements between collections
Solve membership-based DSA problems
A useful question to ask yourself during a DSA problem is:
"Do I just need to know whether I've already seen this value?"
If the answer is yes, a HashSet may be exactly what you need.
The Main Idea
A HashSet is a collection that stores unique elements and uses hashing to provide fast average-time operations.
The most important methods are:
add() → Add an element
contains() → Check whether an element exists
remove() → Remove an element
size() → Get number of elements
isEmpty() → Check whether the set is emptyThe most common DSA pattern looks like:
See an element
↓
Already in HashSet?
↙ ↘
Yes No
↓ ↓
Duplicate Add itHashSet is ideal when you need to store unique values and quickly check whether a value has already been seen.
Once you understand add(), contains(), and remove(), you'll be able to use HashSet for a huge number of DSA problems involving duplicates, uniqueness, and fast membership checks.