Table of contents
1.
Introduction
2.
What is `retainAll()` in Java?  
3.
How Does `retainAll()` Work?  
4.
Syntax of retainAll() Method
5.
Parameters of retainAll()
6.
Return Type of retainAll()
7.
Exceptions of `retainAll()` in Java  
7.1.
1. NullPointerException  
7.2.
2. UnsupportedOperationException  
7.3.
3. ClassCastException  
7.4.
4. ConcurrentModificationException  
8.
Examples of retainAll() in Java
8.1.
Example 1: Using retainAll() with ArrayList
8.2.
Example 2: Using retainAll() with HashSet
8.3.
Example 3: retainAll() When No Common Elements Exist
8.4.
Example 4: Using `retainAll()` with Lists of Strings  
8.5.
Example 5: Using `retainAll()` with Sets  
8.6.
Example 6: Using `retainAll()` with Custom Objects  
9.
Frequently Asked Questions
9.1.
What happens if we pass an empty collection to retainAll()?
9.2.
Can retainAll() be used with custom objects?
9.3.
What is the time complexity of retainAll()?
10.
Conclusion
Last Updated: Mar 11, 2025
Easy

retainAll() in Java

Author Pallavi singh
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

The retainAll() method in Java is used to retain only the elements in a collection that are present in another specified collection. It removes all elements that are not found in the given collection, effectively performing an intersection operation. This method is commonly used in ArrayList, HashSet, and other Collection Framework classes. 

retainAll() in Java

In this article, we will discuss the retainAll() method, its syntax, working, and examples to demonstrate its usage in Java.

What is `retainAll()` in Java?  

The `retainAll()` method is a part of the ` Collections` interface in Java. It is used to modify a collection by retaining only the elements that are also present in another specified collection. In simple terms, it keeps the common elements between two collections & removes the rest.  

This method is particularly useful when you want to find the intersection of two collections. For example, if you have two lists of numbers & you want to keep only the numbers that appear in both lists, `retainAll()` can help you achieve this.  

How Does `retainAll()` Work?  

When you call the `retainAll()` method on a collection, it compares the elements of that collection with the elements of the specified collection. It then removes all elements from the original collection that are not present in the specified collection. If the original collection changes as a result of this operation, the method returns `true`. If no changes are made, it returns `false`.  

For example: 

import java.util.ArrayList;
import java.util.List;

public class RetainAllExample {
    public static void main(String[] args) {
        // Create the first list
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);

       // Create the second list
        List<Integer> list2 = new ArrayList<>();
        list2.add(3);
        list2.add(4);
        list2.add(5);
        list2.add(6);
        // Retain only the common elements in list1
        boolean isChanged = list1.retainAll(list2);

        // Print the result
        System.out.println("Was list1 modified? " + isChanged);
        System.out.println("Updated list1: " + list1);
    }
}
You can also try this code with Online Java Compiler
Run Code


In this Code:   


1. Creating Lists: We create two lists, `list1` & `list2`, with some integer values.  
 

2. Using `retainAll()`: We call the `retainAll()` method on `list1` & pass `list2` as an argument. This modifies `list1` to keep only the elements that are also present in `list2`.  
 

3. Checking for Changes: The `retainAll()` method returns `true` if the original list (`list1`) is modified. In this case, it will return `true` because `list1` is updated to contain only the elements `[3, 4]`. 
 

4. Printing the Result: Finally, we print whether the list was modified & the updated contents of `list1`.  


Output  

Was list1 modified? true
Updated list1: [3, 4]


This example clearly shows how `retainAll()` works. It keeps only the common elements between the two lists & removes the rest.  

Syntax of retainAll() Method

The retainAll() method is defined in the Collection interface and works with various implementations such as ArrayList and HashSet.

boolean retainAll(Collection<?> c)

 

Explanation:

  • This method removes all elements from the collection that are not present in the specified collection c.
     
  • If the collection changes as a result of this operation, it returns true; otherwise, it returns false.

Parameters of retainAll()

The retainAll() method takes a single parameter:

  • Collection<?> c: This represents the collection whose elements should be retained in the current collection.

If the collection c is null, the method will throw a NullPointerException.

Return Type of retainAll()

The retainAll() method returns a boolean value:

  • true – If the collection is modified (i.e., some elements were removed).
     
  • false – If the collection remains unchanged (i.e., all elements were already in the specified collection).

Exceptions of `retainAll()` in Java  

While `retainAll()` is a handy method, it can throw exceptions or lead to unexpected behavior if not used carefully. Understanding these exceptions is crucial to avoid errors in your code. Let’s discuss the common exceptions & scenarios where `retainAll()` might fail.  

1. NullPointerException  

If the specified collection passed to `retainAll()` is `null`, the method will throw a `NullPointerException`. This happens because the method tries to access the elements of the specified collection, but since it’s `null`, it cannot proceed.  

Example:  

import java.util.ArrayList;
import java.util.List;

public class RetainAllExceptionExample {
    public static void main(String[] args) {
        // Create a list
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);

        // Pass null as the argument to retainAll()
        try {
            list1.retainAll(null);
        } catch (NullPointerException e) {
            System.out.println("Exception caught: " + e.getMessage());
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Exception caught: null

 

Explanation:  

We created a list `list1` with some elements.  
 

When we called `retainAll(null)`, the method threw a `NullPointerException` because the specified collection was `null`.  

2. UnsupportedOperationException  

Some collections in Java are immutable, meaning their elements cannot be modified. If you try to use `retainAll()` on an immutable collection, it will throw an `UnsupportedOperationException`.  

Example:  

import java.util.Collections;
import java.util.List;

public class RetainAllUnsupportedExample {
    public static void main(String[] args) {
        // Create an immutable list
        List<Integer> immutableList = Collections.singletonList(1);


        // Try to modify the immutable list using retainAll()
        try {
            immutableList.retainAll(Collections.singletonList(2));
        } catch (UnsupportedOperationException e) {
            System.out.println("Exception caught: " + e.getMessage());
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Exception caught: null


Explanation:  

We created an immutable list using `Collections.singletonList(1)`.  
 

When we tried to call `retainAll()` on this list, it threw an `UnsupportedOperationException` because the list cannot be modified.  

3. ClassCastException  

If the elements of the collections are not compatible (e.g., trying to compare integers with strings), the `retainAll()` method will throw a `ClassCastException`.  

Example:  

import java.util.ArrayList;
import java.util.List;


public class RetainAllClassCastExample {
    public static void main(String[] args) {
        // Create a list of integers
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);


        // Create a list of strings
        List<String> list2 = new ArrayList<>();
        list2.add("1");
        list2.add("2");


        // Try to retain elements between incompatible collections
        try {
            list1.retainAll(list2);
        } catch (ClassCastException e) {
            System.out.println("Exception caught: " + e.getMessage());
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Exception caught: java.lang.String cannot be cast to java.lang.Integer


Explanation:  

We created two lists: one with integers & another with strings.  
 

When we tried to use `retainAll()` between these incompatible collections, it threw a `ClassCastException`.  

4. ConcurrentModificationException  

If a collection is modified while it’s being iterated over (e.g., in a loop), it can throw a `ConcurrentModificationException`. This can happen if `retainAll()` is used improperly in such scenarios.  

Example:  

import java.util.ArrayList;
import java.util.List;


public class RetainAllConcurrentModificationExample {
    public static void main(String[] args) {
        // Create a list
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);


        // Try to modify the list while iterating over it
        try {
            for (Integer num : list1) {
                list1.retainAll(List.of(2, 3));
            }
        } catch (Exception e) {
            System.out.println("Exception caught: " + e.getMessage());
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Exception caught: null


Explanation:  

We created a list & tried to modify it using `retainAll()` while iterating over it.  
 

This caused a `ConcurrentModificationException` because the list was being modified during iteration.  

Examples of retainAll() in Java

Let’s look at some practical examples to understand how retainAll() works.

Example 1: Using retainAll() with ArrayList

import java.util.*;
public class RetainAllExample {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry", "Date"));
        ArrayList<String> list2 = new ArrayList<>(Arrays.asList("Banana", "Date", "Fig"));
        System.out.println("Before retainAll: " + list1);
        
        list1.retainAll(list2);
        System.out.println("After retainAll: " + list1);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:

Before retainAll: [Apple, Banana, Cherry, Date]
After retainAll: [Banana, Date]


Explanation:

  • The retainAll() method retains only the elements "Banana" and "Date" because they are present in both lists.
     
  • The elements "Apple" and "Cherry" are removed.

Example 2: Using retainAll() with HashSet

import java.util.*;
public class RetainAllSetExample {
    public static void main(String[] args) {
        HashSet<Integer> set1 = new HashSet<>(Arrays.asList(10, 20, 30, 40, 50));
        HashSet<Integer> set2 = new HashSet<>(Arrays.asList(20, 40, 60));
        System.out.println("Before retainAll: " + set1);
        set1.retainAll(set2);
        System.out.println("After retainAll: " + set1);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:

Before retainAll: [50, 20, 40, 10, 30]
After retainAll: [20, 40]

 

Explanation:

  • Only 20 and 40 are common in both sets, so they are retained.
     
  • The other elements 10, 30, and 50 are removed.

Example 3: retainAll() When No Common Elements Exist

import java.util.*;
public class RetainAllNoMatch {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>(Arrays.asList("Red", "Blue", "Green"));
        ArrayList<String> list2 = new ArrayList<>(Arrays.asList("Yellow", "Pink"));
        System.out.println("Before retainAll: " + list1);
        boolean isModified = list1.retainAll(list2);
        System.out.println("After retainAll: " + list1);
        System.out.println("Was the list modified? " + isModified);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:

Before retainAll: [Red, Blue, Green]
After retainAll: []
Was the list modified? true


Explanation:

  • Since there are no common elements, all elements are removed, and the list becomes empty.
     
  • The method returns true, indicating that the list was modified.

Example 4: Using `retainAll()` with Lists of Strings  

In this example, we’ll use `retainAll()` to find common elements between two lists of strings.  

import java.util.ArrayList;
import java.util.List;

public class RetainAllStringExample {
    public static void main(String[] args) {
        // Create the first list of strings
        List<String> list1 = new ArrayList<>();
        list1.add("apple");
        list1.add("banana");
        list1.add("cherry");
        list1.add("date");

        // Create the second list of strings
        List<String> list2 = new ArrayList<>();
        list2.add("banana");
        list2.add("date");
        list2.add("fig");
        list2.add("grape");

        // Retain only the common elements in list1
        boolean isChanged = list1.retainAll(list2);

        // Print the result
        System.out.println("Was list1 modified? " + isChanged);
        System.out.println("Updated list1: " + list1);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Was list1 modified? true
Updated list1: [banana, date]


Explanation:  

We created two lists of strings: `list1` & `list2`.  
 

The `retainAll()` method was called on `list1` with `list2` as the argument.  
 

Only the common elements (`"banana"` & `"date"`) were retained in `list1`.  

Example 5: Using `retainAll()` with Sets  

In this example, we’ll use `retainAll()` with sets to find common elements.  

import java.util.HashSet;
import java.util.Set;
public class RetainAllSetExample {
    public static void main(String[] args) {
        // Create the first set
        Set<Integer> set1 = new HashSet<>();
        set1.add(10);
        set1.add(20);
        set1.add(30);
        set1.add(40);
        // Create the second set
        Set<Integer> set2 = new HashSet<>();
        set2.add(30);
        set2.add(40);
        set2.add(50);
        set2.add(60);

        // Retain only the common elements in set1
        boolean isChanged = set1.retainAll(set2);

        // Print the result
        System.out.println("Was set1 modified? " + isChanged);
        System.out.println("Updated set1: " + set1);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Was set1 modified? true
Updated set1: [30, 40]


Explanation:  

  • We created two sets of integers: `set1` & `set2`.  
     
  • The `retainAll()` method was called on `set1` with `set2` as the argument.  
     
  • Only the common elements (`30` & `40`) were retained in `set1`.  

Example 6: Using `retainAll()` with Custom Objects  

In this example, we’ll use `retainAll()` with a list of custom objects. For this to work, the custom class must override the `equals()` & `hashCode()` methods.  

import java.util.ArrayList;
import java.util.List;

class Student {
    private int id;
    private String name;


    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Student student = (Student) obj;
        return id == student.id && name.equals(student.name);
    }

    @Override
    public int hashCode() {
        return id + name.hashCode();
    }

    @Override
    public String toString() {
        return "Student{id=" + id + ", name='" + name + "'}";
    }
}

public class RetainAllCustomObjectExample {
    public static void main(String[] args) {
        // Create the first list of students
        List<Student> list1 = new ArrayList<>();
        list1.add(new Student(1, "Alice"));
        list1.add(new Student(2, "Bob"));
        list1.add(new Student(3, "Charlie"));

        // Create the second list of students
        List<Student> list2 = new ArrayList<>();
        list2.add(new Student(2, "Bob"));
        list2.add(new Student(3, "Charlie"));
        list2.add(new Student(4, "David"));

        // Retain only the common students in list1
        boolean isChanged = list1.retainAll(list2);
        // Print the result
        System.out.println("Was list1 modified? " + isChanged);
        System.out.println("Updated list1: " + list1);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output:  

Was list1 modified? true
Updated list1: [Student{id=2, name='Bob'}, Student{id=3, name='Charlie'}]


Explanation:  

  • We created a `Student` class with `id` & `name` fields. The `equals()` & `hashCode()` methods were overridden to compare students based on their `id` & `name`.  
     
  • Two lists of `Student` objects were created: `list1` & `list2`.  
     
  • The `retainAll()` method was called on `list1` with `list2` as the argument.  
     
  • Only the common students (`Bob` & `Charlie`) were retained in `list1`.  

Frequently Asked Questions

What happens if we pass an empty collection to retainAll()?

If an empty collection is passed, the calling collection will be emptied because no elements can be retained.

Can retainAll() be used with custom objects?

Yes, but the class must override the equals() method to correctly compare objects.

What is the time complexity of retainAll()?

The time complexity of retainAll() is O(n × m), where n is the size of the original collection and m is the size of the collection being compared.

Conclusion

In this article, we discussed the retainAll() method in Java, which is used in collections to retain only the elements present in another specified collection. It helps in filtering lists, performing set operations, and maintaining common elements between collections. This method is useful for optimizing data processing and ensuring relevant data is preserved.

Live masterclass