A Set Stores Unique Values
A HashSet (from java.util) is a collection that holds each value at most once. There are no keys and no values paired up like in a HashMap - just a bag of distinct elements. Its whole job is to answer one question fast: "is this thing in here?"
There is one type parameter, <ElementType>. As with ArrayList and HashMap, you typically type the variable as the Set interface and construct a HashSet.
add Returns Whether It Was New
add does not just store the value - it returns a boolean telling you whether the set actually changed. Adding a value that is already present returns false and leaves the set untouched.
That return value is genuinely useful: if (!seen.add(x)) { /* x is a repeat */ } lets you detect duplicates in a single line as you go.
Removing Duplicates From a List
Because a set rejects repeats, the fastest way to dedupe a collection is to dump it into one. A HashSet constructor accepts any other collection:
This is the most common reason beginners reach for a set. Just know you lose the original ordering in the round trip - use LinkedHashSet if order matters (covered below).
contains, remove, and size
The everyday operations mirror the other collections:
The big win over an ArrayList is contains. A list has to walk every element to answer it (O(n)); a HashSet jumps almost straight to the answer (roughly O(1)). When you find yourself calling list.contains(...) inside a loop, that is usually the signal to switch to a set.
Set Math: Union, Intersection, Difference
Sets shine when you combine them. The methods read like plain English once you know which is which:
The key gotcha: addAll, retainAll, and removeAll mutate the set they're called on. That's why each example copies a into a fresh HashSet first - otherwise you'd destroy your original. Build a new set for each result.
HashSet Does Not Keep Order
Like HashMap, a HashSet makes no promise about iteration order, and the order can differ between runs. If you need predictability:
LinkedHashSetpreserves insertion order - the order you added elements.TreeSetkeeps elements sorted by natural ordering (or aComparatoryou supply).
All three implement the Set interface, so swapping between them is a one-line change to the constructor.
Elements Must Be Hashable
A HashSet is backed by a HashMap under the hood, so the same rule applies: it locates elements by hashing them, which means an element's hashCode() and equals() must agree. Built-in types like String and Integer already get this right, which is why duplicate "java" strings collapse correctly above. If you store instances of your own class, override both equals and hashCode - otherwise two objects that are "equal" in meaning will be treated as distinct, and contains and dedup will silently fail.
Next: Iterating Collections
You've now met the three workhorse collections - ArrayList, HashMap, and HashSet. Each one you walk through a little differently, and there are subtle traps (like modifying a collection while looping over it). Next we'll pull it all together and cover iterating collections cleanly with the for-each loop, iterators, and forEach.
Frequently Asked Questions
How do you create a HashSet in Java?
Declare it with one type parameter - the element type - and call the constructor: Set<String> tags = new HashSet<>();. Add values with tags.add("java"); and test membership with tags.contains("java");. Import java.util.HashSet and java.util.Set.
What is the difference between a HashSet and an ArrayList in Java?
An ArrayList keeps every element you add (duplicates included) in insertion order and is indexed by position. A HashSet stores only unique values, makes no promise about order, has no index, and its contains check is roughly constant time instead of scanning the whole list. Reach for a HashSet when you care about uniqueness or fast membership, not position.
How do you remove duplicates from a list in Java?
Pass the list to a HashSet constructor: Set<String> unique = new HashSet<>(list);. The set drops repeated values automatically. If you need a list back (and don't mind losing order), wrap it again: new ArrayList<>(unique). Use a LinkedHashSet instead if you want the original order preserved.