Java - Removing duplicates in an ArrayList
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Removing duplicates from an ArrayList is easy once you decide which behavior you actually need. Some solutions keep insertion order, some do not, and some rely on correct equals and hashCode implementations for custom objects. The best approach depends on whether you care most about speed, order preservation, or mutating the original list in place.
Use LinkedHashSet to Remove Duplicates and Keep Order
For many cases, the cleanest solution is converting the list to a LinkedHashSet and back. LinkedHashSet removes duplicates while preserving insertion order.
This is usually the best default when list order matters.
Use HashSet Only If Order Does Not Matter
If insertion order is irrelevant, HashSet is slightly simpler conceptually, but it does not preserve the original order.
Do not choose this if the resulting list is shown to users or used in order-sensitive logic.
Use Streams for Readable Pipeline Code
Java Streams offer a concise way to express de-duplication:
distinct() preserves encounter order for ordered streams, which makes it a good modern option when you already use stream pipelines.
In-Place Removal with a Tracking Set
If you must mutate the existing ArrayList, use removeIf with a tracking set.
This preserves the first occurrence and removes later duplicates from the same list object.
Custom Objects Need Correct Equality
For custom object lists, duplicate removal depends on equals and hashCode. If those are not implemented consistently, set-based approaches and distinct() will behave incorrectly.
Without correct equality semantics, Java cannot know what "duplicate" means.
Common Pitfalls
- Using
HashSetwhen insertion order must be preserved. - Forgetting that custom objects need correct
equalsandhashCode. - Removing duplicates in place when callers expected the original list to remain unchanged.
- Using nested loops for large lists when set-based solutions are simpler and faster.
- Assuming
distinct()changes the original list rather than returning a new stream result.
Summary
- '
LinkedHashSetis the simplest ordered de-duplication strategy for manyArrayListcases.' - '
HashSetworks when order is irrelevant.' - Stream
distinct()is a clean option in modern pipeline-style code. - '
removeIfplus a tracking set is useful when you need in-place mutation.' - For custom types, duplicate removal is only as good as your
equalsandhashCodemethods.
Related reading
- Java - Sort one array based on values of another array?
- Java 8 List<V> into Map<K, V>
- Java 8 Stream and operation on arrays
- Java & RabbitMQ - Queueing & Multithreading - Or Couchbase as Job-Queue
- Java - removing first character of a string
- Java - sending HTTP parameters via POST method easily
- Java array reflection isArray vs. instanceof
- Java Array Sort descending?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.