HashSet in Java
HashSet in Java is a class that implements the Set interface using a hash table. It is used to store unique elements and to check very quickly whether an element is present. HashSet does not keep elements in any particular order. It is the most commonly used Set. In this lesson, you will learn how to use HashSet, why its order looks random, and why your own classes need equals and hashCode to work with it.
Declaration
public class HashSet<E> extends AbstractSet<E>
implements Set<E>, Cloneable, SerializableFeatures of HashSet
- Unique elements: duplicates are ignored.
- No order: the iteration order depends on hash codes and can change as the set grows.
- Allows one
null. - Fast:
add,removeandcontainstake constant time on average. - Backed by a
HashMap: each element is stored as a key (see "HashSet Internal Working"). - Not synchronized.
Constructors
| Constructor | Description |
|---|---|
HashSet() | It creates an empty set with default capacity 16 and load factor 0.75. |
HashSet(int initialCapacity) | It creates an empty set with the given capacity. |
HashSet(Collection<? extends E> c) | It creates a set containing the elements of another collection. |
Example: Basic HashSet Operations
Let's see an example of adding, checking and removing.
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args) {
Set<String> emails = new HashSet<>();
emails.add("navika@mail.com");
emails.add("srihitha@mail.com");
emails.add("navika@mail.com");
emails.add("advitha@mail.com");
System.out.println("Count: " + emails.size());
System.out.println("Has Srihitha? "
+ emails.contains("srihitha@mail.com"));
emails.remove("advitha@mail.com");
System.out.println("Count after remove: " + emails.size());
}
}Count: 3
Has Srihitha? true
Count after remove: 2Explanation: Navika's email is added twice but stored once, so the count is 3. contains finds an element without looking through the whole set, and remove deletes one.
Example: Removing Duplicates from a List
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Dedupe {
public static void main(String[] args) {
List<Integer> marks = List.of(85, 91, 85, 78, 91, 85);
Set<Integer> unique = new HashSet<>(marks);
System.out.println("Unique count: " + unique.size());
List<Integer> sorted = new ArrayList<>(unique);
sorted.sort(null);
System.out.println("Unique sorted: " + sorted);
}
}Unique count: 3
Unique sorted: [78, 85, 91]Explanation: Passing the list to the HashSet constructor removes every duplicate in one step. Because a HashSet has no order, the result is copied into a list and sorted before printing (sort(null) means natural order).
equals and hashCode Are Required
HashSet decides whether two objects are the "same" using hashCode and equals. A class that doesn't override them uses object identity, so two objects with the same data are treated as different:
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class NeedsEquals {
static class Plain {
String name;
Plain(String name) { this.name = name; }
}
static class Proper {
String name;
Proper(String name) { this.name = name; }
@Override
public boolean equals(Object o) {
return o instanceof Proper p && name.equals(p.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static void main(String[] args) {
Set<Plain> plain = new HashSet<>();
plain.add(new Plain("Navika"));
plain.add(new Plain("Navika"));
System.out.println("Without equals/hashCode: " + plain.size());
Set<Proper> proper = new HashSet<>();
proper.add(new Proper("Navika"));
proper.add(new Proper("Navika"));
System.out.println("With equals/hashCode: " + proper.size());
}
}Without equals/hashCode: 2
With equals/hashCode: 1Explanation: The two Plain objects have different identity hash codes, so both are kept. Proper defines equality by name, so the second Navika is recognized as a duplicate. A record gets correct equals and hashCode automatically.
Common Mistakes
Relying on the printed order of a HashSet. It isn't guaranteed and can change.
Overriding equals without hashCode. Equal objects then land in different buckets and both are kept.
Calling get(0) on a set. Sets have no index; iterate instead.
Interview Corner
How does HashSet prevent duplicates?
HashSet stores each element as a key in an internal HashMap. When adding, it computes the element's hashCode to find a bucket and uses equals to compare with the elements already there. If an equal element exists, add returns false and nothing changes. This is why elements need consistent equals and hashCode implementations.
Practice
- Easy: Read ten numbers and print how many distinct numbers there were.
- Harder: Create a
Bookclass with ISBN and title, where two books are equal when their ISBNs match. Add three books, two with the same ISBN, to aHashSetand print the size.
Key Takeaways
Was this tutorial helpful?