Set Operations
Fast recall
Quick revision
Core answer
boolean, so copy it first (new HashSet<>(original)) when you need to keep the original.Knowledge of Set API methods and understanding of mathematical set operations
Not realizing these methods mutate the original Set, losing data unexpectedly
Show both the mutating API approach and the immutable Stream-based approach for modern Java code
Interview-ready guide
Interview answer
Java provides three Collection methods for set operations — addAll for union, retainAll for intersection, and removeAll for difference.
Union combines both sets. You call addAll on one set and pass the other, and it adds all elements from the second set into the first. Intersection finds common elements.
You call retainAll and it keeps only the elements that exist in both sets, removing everything else. Difference removes elements. You call removeAll and it removes all elements from the calling set that exist in the other set.
The really important thing to know is these methods mutate the calling set in place. They don't return a new set — they modify the original and return a boolean telling you if anything changed. This trips up a lot of freshers.
If you need to keep your original data, you must create a copy first using new HashSet of the original set, then perform the operation on the copy.
For example, if you have active users and premium users and you want the intersection without losing the original active users, you'd do new HashSet of active users, then call retainAll with premium users on the copy. Modern Java also gives you an immutable approach using Streams. For union, you can use Stream dot concat to combine two streams and collect to a set.
For intersection, you'd stream the first set, filter by whether the second set contains each element, then collect. This creates a new set without touching the originals, which is cleaner and safer in functional-style code. One mistake freshers make is calling these methods directly on the original set and losing their data.
Another is expecting a new set to be returned, but the return value is just a boolean.
Set Operations
Direct Answer
Use addAll for union, retainAll for intersection, and removeAll for difference. These mutate the calling Set in place and return a boolean, so copy it first (new HashSet<>(original)) when you need to keep the original.
Code Example
var activeUsers = new HashSet<>(Set.of("alice", "bob", "charlie"));
var premiumUsers = new HashSet<>(Set.of("bob", "diana"));
// Union - combine both sets (mutates a copy, not activeUsers)
var unionSet = new HashSet<>(activeUsers);
unionSet.addAll(premiumUsers); // {alice, bob, charlie, diana}
// Intersection - only common elements (mutates copy)
var intersectionSet = new HashSet<>(activeUsers);
intersectionSet.retainAll(premiumUsers); // {bob}
// Difference - elements in first but not second (mutates copy)
var differenceSet = new HashSet<>(activeUsers);
differenceSet.removeAll(premiumUsers); // {alice, charlie}
// Immutable Stream approach for union
var unionStream = Stream.concat(
activeUsers.stream(),
premiumUsers.stream()
).collect(Collectors.toSet());
// Immutable intersection
var intersectionStream = activeUsers.stream()
.filter(premiumUsers::contains)
.collect(Collectors.toSet());
Common Mistakes & Pitfalls
- Forgetting to copy before mutating: Calling
addAll,retainAll, orremoveAlldirectly on the originalSetloses your data permanently — create a copy withnew HashSet<>(original)first if you still need it. - Expecting a new Set to be returned: Freshers think these return a new
Setlike Stream operations do, but they returnbooleanand mutate in place —var result = setA.retainAll(setB)makesresulta boolean, not a Set. - Wrong difference direction:
setA.removeAll(setB)gives elements in A but not B, whilesetB.removeAll(setA)gives the opposite — order matters for difference.
Check your understanding
Answer these without looking back at the article.
- What is the difference between addAll() on a List vs a Set?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.