ArrayList Remove Duplicates in Java
Problem
A LinkedHashSet stores only unique elements and remembers insertion order, which makes wrapping an ArrayList in one a quick way to drop duplicates without scrambling the list.
Given an ArrayList with repeated values, produce a new list containing each value only once, in its original order.
Java Program
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class ArrayListRemoveDuplicates {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Apple");
names.add("Banana");
names.add("Apple");
names.add("Cherry");
names.add("Banana");
// LinkedHashSet drops duplicates automatically, keeping first-seen order
List<String> unique = new ArrayList<>(new LinkedHashSet<>(names));
System.out.println(unique);
}
}Output
Core Logic
Feeding the list straight into a LinkedHashSet's constructor collapses every duplicate automatically, and converting the result back to a list restores a list-shaped return type.
- 1
new LinkedHashSet<>(names)copies every element fromnamesinto the set, silently skipping any value already present. - 2Unlike a plain
HashSet, aLinkedHashSetkeeps track of the order elements were first inserted in, so nothing gets shuffled. - 3
new ArrayList<>(uniqueSet)copies the deduplicated set's contents back into a freshArrayList. - 4The final list holds the same elements as the original, minus every repeat, in their original first-seen order.
[Apple, Banana, Apple, Cherry, Banana], the set keeps only the first Apple and first Banana, producing [Apple, Banana, Cherry].Key Point: Choosing LinkedHashSet over a plain HashSet is what preserves the original order — a plain HashSet would still remove duplicates correctly, but the resulting order would be unspecified.
Why: Building the LinkedHashSet visits each of the n elements once, with an O(1) average-case check-and-insert per element, and the set holds up to n distinct elements.
Key Concepts
Approach 2: Java 8
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ArrayListRemoveDuplicatesStream {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Apple");
names.add("Banana");
names.add("Apple");
names.add("Cherry");
names.add("Banana");
// distinct() drops repeats while streaming, keeping first-seen order
List<String> unique = names.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(unique);
}
}
Output
Core Logic
Stream's distinct() drops repeated elements while streaming, so filtering and collecting in one pipeline reproduces the same deduplicated, order-preserving result without an intermediate 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 — later duplicates are silently dropped. - 3
.collect(Collectors.toList())gathers the surviving elements into a new List. - 4Like
distinct()'s LinkedHashSet-based cousin, encounter order is preserved — the first occurrence of each value keeps its original position.
[Apple, Banana, Apple, Cherry, Banana] through distinct() keeps only the first Apple and first Banana, producing [Apple, Banana, Cherry].Key Point: distinct() reaches the same result as the LinkedHashSet technique without ever naming a Set — it's the more declarative choice when deduplication is just one step in a larger stream 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.