Remove Duplicates Using Set in Java
Problem
A Set can never hold two equal elements, so building one from a List's contents and reading it back strips every duplicate in a single step.
Given a List of names with repeats, produce a new List holding each name exactly once, in its original order.
Java Program
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class RemoveDuplicatesUsingSet {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Alice", "Charlie", "Bob", "Dave");
// Building a LinkedHashSet from the list drops duplicates while keeping first-seen order
LinkedHashSet<String> uniqueNames = new LinkedHashSet<>(names);
List<String> result = new ArrayList<>(uniqueNames);
System.out.println(result);
}
}Output
Core Logic
Passing the List straight into a LinkedHashSet's constructor drops every duplicate automatically, and converting that Set back into a List hands back a clean, order-preserving result in two lines.
- 1
new LinkedHashSet<>(names)builds a Set directly from the List, and a Set can never contain the same value twice — every duplicate is silently dropped at construction. - 2
LinkedHashSetspecifically remembers the order elements were first inserted in, unlike a plainHashSet, whose iteration order isn't guaranteed. - 3
new ArrayList<>(uniqueNames)reads the deduplicated Set back into a List, since a List is usually more convenient to keep working with afterward. - 4Neither step needs a manual loop — both the deduplication and the conversion happen through constructor calls alone.
[Alice, Bob, Alice, Charlie, Bob, Dave], the second Alice and second Bob never make it into the Set, leaving [Alice, Bob, Charlie, Dave] in their original first-seen order.Key Point: This whole deduplication is really just two constructor calls chained together — funnel the List into a LinkedHashSet, then read the Set back out into a List.
Why: Building the Set visits every element once, and both the Set and the resulting List can hold up to n distinct elements.
Key Concepts
Approach 2: Java 8
import java.util.List;
import java.util.stream.Collectors;
public class RemoveDuplicatesUsingSetStream {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Alice", "Charlie", "Bob", "Dave");
// distinct() drops repeats while streaming, keeping first-seen order
List<String> result = names.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(result);
}
}
Output
Core Logic
Stream's distinct() drops repeated elements while streaming, reproducing the same order-preserving deduplication as the two-constructor version without naming a Set at all.
- 1
names.stream()opens a stream over the original list, duplicates included. - 2
.distinct()keeps only the first occurrence of each element, usingequals()to detect repeats. - 3
.collect(Collectors.toList())gathers the surviving elements into a new List, preserving encounter order. - 4No
LinkedHashSetor intermediateArrayListconstructor call is needed — the whole deduplication happens in one pipeline.
[Alice, Bob, Alice, Charlie, Bob, Dave] through distinct() keeps only the first Alice and first Bob, producing [Alice, Bob, Charlie, Dave].Key Point: distinct() reaches the same result as funneling through a LinkedHashSet without ever naming a Set — it's the more declarative choice when deduplication is just one step in a larger pipeline.
Why: distinct() internally tracks seen elements (typically backed by a hash set) to check each of the n elements once, and the resulting list holds up to n distinct elements.