ArrayList
Java
Programming
Data Structures
Coding Solutions

How do I remove repeated elements from 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.

Practice algorithms

Introduction

To remove duplicate values from an ArrayList in Java, the best method depends on whether you need to preserve the original order. The most common practical answer is to use a LinkedHashSet, because it removes duplicates and keeps insertion order.

The Quickest Order-Preserving Solution

If order matters, convert the list to a LinkedHashSet and then back to a list:

java
1import java.util.ArrayList;
2import java.util.Arrays;
3import java.util.LinkedHashSet;
4
5public class RemoveDuplicatesDemo {
6    public static void main(String[] args) {
7        ArrayList<Integer> list = new ArrayList<>(
8            Arrays.asList(1, 2, 3, 2, 4, 5, 5, 6)
9        );
10
11        ArrayList<Integer> unique = new ArrayList<>(new LinkedHashSet<>(list));
12        System.out.println(unique);
13    }
14}

Output:

text
[1, 2, 3, 4, 5, 6]

This is usually the cleanest answer because it keeps the first occurrence of each value and removes later repeats.

If Order Does Not Matter

If you only care about uniqueness and do not care about element order, a plain HashSet is enough:

java
1import java.util.ArrayList;
2import java.util.Arrays;
3import java.util.HashSet;
4
5public class RemoveDuplicatesDemo {
6    public static void main(String[] args) {
7        ArrayList<Integer> list = new ArrayList<>(
8            Arrays.asList(1, 2, 3, 2, 4, 5, 5, 6)
9        );
10
11        ArrayList<Integer> unique = new ArrayList<>(new HashSet<>(list));
12        System.out.println(unique);
13    }
14}

This may print the values in a different order, because HashSet does not preserve insertion order.

Java Streams

In Java 8 and later, stream().distinct() is a concise alternative:

java
1import java.util.ArrayList;
2import java.util.Arrays;
3import java.util.List;
4import java.util.stream.Collectors;
5
6public class RemoveDuplicatesDemo {
7    public static void main(String[] args) {
8        ArrayList<Integer> list = new ArrayList<>(
9            Arrays.asList(1, 2, 3, 2, 4, 5, 5, 6)
10        );
11
12        List<Integer> unique = list.stream()
13                                   .distinct()
14                                   .collect(Collectors.toList());
15
16        System.out.println(unique);
17    }
18}

distinct() preserves encounter order for sequential streams, so it behaves similarly to the LinkedHashSet approach.

In-Place Removal Versus Creating a New List

Most examples create a new collection. That is usually fine and keeps the code readable. If you really need to mutate the existing list object, you can clear it and add the unique values back:

java
1ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 2, 4, 5, 5, 6));
2LinkedHashSet<Integer> set = new LinkedHashSet<>(list);
3list.clear();
4list.addAll(set);

That preserves the same ArrayList instance while removing duplicates.

Equality Rules Matter

Duplicate removal depends on equals() and hashCode(). For built-in types such as String and Integer, this usually works as expected. For custom objects, you must implement those methods correctly.

java
1class Person {
2    String email;
3
4    Person(String email) {
5        this.email = email;
6    }
7
8    @Override
9    public boolean equals(Object obj) {
10        if (this == obj) return true;
11        if (!(obj instanceof Person other)) return false;
12        return email.equals(other.email);
13    }
14
15    @Override
16    public int hashCode() {
17        return email.hashCode();
18    }
19}

Without correct equality logic, two objects that look like duplicates to a human may still be treated as distinct by the set.

Common Pitfalls

  • Using HashSet when order matters often surprises people because the result order can change.
  • Forgetting that duplicate removal relies on equals() and hashCode() breaks the solution for custom object types.
  • Writing a manual nested-loop removal routine is usually slower and less readable than using set-based approaches.
  • Assuming stream().distinct() changes the original list in place is incorrect; it produces a new stream result.
  • Removing while iterating over the same ArrayList manually can lead to skipped elements or ConcurrentModificationException depending on the approach.

Summary

  • The usual order-preserving solution is new ArrayList<>(new LinkedHashSet<>(list)).
  • Use HashSet only when order is irrelevant.
  • 'stream().distinct() is a concise modern alternative.'
  • For custom objects, duplicate removal depends on correct equals() and hashCode() implementations.
  • Prefer clear set-based solutions over manual duplicate-removal loops unless you have a very specific reason not to.

Related reading
Course
Intermediate
27 lessons
15 hours
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 course
Track 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.

Practice algorithms

All Rights Reserved.