Use Collection#retainAll().

listA.retainAll(listB);
// listA now contains only the elements which are also contained in listB.

If you want to avoid that changes are being affected in listA, then you need to create a new one.

List<Integer> common = new ArrayList<>(listA);
common.retainAll(listB);
// common now contains only the elements which are contained in listA and listB.

If you're a fan of streams, best what you could do is to Stream#filter() on Collection#contains() of the other list.

List<Integer> common = listA.stream().filter(listB::contains).toList();
// common now contains only the elements which are contained in listA and listB.

It's only at least twice slower.

Answer from BalusC on Stack Overflow
🌐
How to do in Java
howtodoinjava.com › home › collections framework › java arraylist › how to compare two lists in java
How to Compare Two Lists in Java - HowToDoInJava
September 20, 2023 - Also, the CollectionUtils.intersection() method can be used that returns the common elements in two lists. List<String> listOfCommonItems = (List<String>) CollectionUtils.intersection(listTwo, listOne); Assertions.assertTrue(CollectionUtils...
🌐
Baeldung
baeldung.com › home › java › java list › finding the differences between two lists in java
Finding the Differences Between Two Lists in Java | Baeldung
January 28, 2026 - We’ll try a few different approaches, including plain Java (with and without Streams), and third-party libraries, such as Guava and the Apache Commons Collections. Let’s start by defining two lists, which we’ll use to test out our examples: public class FindDifferencesBetweenListsUnitTest { private static final List listOne = Arrays.asList("Jack", "Tom", "Sam", "John", "James", "Jack"); private static final List listTwo = Arrays.asList("Jack", "Daniel", "Sam", "Alan", "James", "George"); } We can create a copy of one list and then remove all the elements common with the other using the List method removeAll():
🌐
Coderanch
coderanch.com › t › 743146 › java › Find-common-elements-lists-list
Find common elements between 2 lists where list elements are objects (Features new in Java 8 forum at Coderanch)
June 8, 2021 - You simply need to be aware that comparisons will be done based on object identity. Well, you did say Set, so the fact that this option of data structure choice for a particular Map exists doesn't gainsay that: https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/IdentityHashMap.html I note that there is no IdentityHashSet, and the above structure uses Reference Equality for BOTH keys AND values.
🌐
GeeksforGeeks
geeksforgeeks.org › java › find-common-elements-in-two-arraylists-in-java
Find common elements in two ArrayLists in Java - GeeksforGeeks
July 11, 2025 - ... // Java Program to find common elements // in two ArrayLists // Using retainAll() method // import ArrayList package import java.util.ArrayList; public class GFG { // main method public static void main(String[] args) { // create ArrayList ...
🌐
amitph
amitph.com › home › java › comparing two lists in java
Comparing Two Lists In Java - amitph
November 22, 2024 - To do that, we can create a Stream of the first List and use the filter() method to retain only the elements in the second List. Example of using Java Streams to find common elements between two Java Lists.
🌐
DevQA
devqa.io › java-compare-two-arraylists
Java Compare Two Lists
March 17, 2020 - public class CompareTwoArrayLists { public static void main(String[] args) { ArrayList<Integer> listOne = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); ArrayList<Integer> listTwo = new ArrayList<>(Arrays.asList(1, 2, 4, 5, 6, 7)); ...
🌐
DZone
dzone.com › coding › languages › how to compare list objects in java 7 vs. java 8
How to Compare List Objects in Java 7 vs. Java 8
June 1, 2018 - All elements of a List exist in another List. Now, developing these use cases is very easy in Java 7 with relatively few lines of code. The following is an example where we are comparing two Lists in Java 7 and checking if any element from List 1 exists in List 2.
Find elsewhere
🌐
Techie Delight
techiedelight.com › find-common-elements-two-lists-java
Find common elements in two lists in Java | Techie Delight
Techie Delight is a leading platform for technical interview preparation. Prepare for your coding interview with Techie Delight. Improve your algorithmic skills and crack interviews with top tech companies.
🌐
CopyProgramming
copyprogramming.com › howto › java-8-compare-two-lists-of-objects
Comparing Two Lists of Objects in Java 8: Complete Guide with Latest Features & Best Practices 2026 - Complete guide with latest features
December 27, 2025 - The simplest approach to compare two lists in java is the List.equals() method, which checks if both lists have the same size and elements in exactly the same order.
🌐
CopyProgramming
copyprogramming.com › howto › java-java-stream-compare-two-lists-code-example
Arraylist: Code Example for Comparing Two Lists Using Java Streams
May 14, 2023 - Comparing values of objects in two lists with Java8 Streams and adding a value to a sub-object in the first list, Using Stream to Compare Two Lists and Retrieve Elements from Comparison List, Using .stream() to Compare Integers in Java: A Comparison Guide
🌐
YouTube
youtube.com › java inspires
How to get Common elements from two lists using Stream API filter | Java Inspires - YouTube
In this video, we will see How to get Common elements from two lists using Stream API filter().Find source code here :: https://javainspires.blogspot.com/20...
Published   March 30, 2021
Views   5K
🌐
Javaprogramto
javaprogramto.com › 2020 › 04 › how-to-compare-two-arraylist-for-equality-in-java.html
How to compare two ArrayList for equality in Java 8? ArrayList equals() or containsAll() methods works? JavaProgramTo.com
June 13, 2021 - A quick program to compare two list values inside the lists. This equality check is done using the ArrayList equals() method and containsAll() method. Java 8 Stream API Example as well.
🌐
Quora
quora.com › How-can-two-lists-of-objects-be-compared-in-Java
How can two lists of objects be compared in Java? - Quora
Google Guava’s Maps.difference (after mapping), or java-diff-utils for sequence diffs (gives edit script), or Apache Commons Collections for collection utilities. For complex objects, base diff on unique identifier (id) to detect modifications rather than object equality. ... Decide null semantics upfront. List.equals handles null elements, but custom comparators must check for nulls.
🌐
YouTube
youtube.com › watch
How to Find common elements between two lists in Java
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
Top answer
1 of 1
1

I find the current algorithm of "adding and removing" to be a streamed implementation of non-functional thinking. Rather than adding and removing, I encourage you to think in terms of joining (akin to SQL outer-joining) and filtration, which are more functional concepts. In this interpretation, your "local" collection is on the left-hand side of a left outer join, and your "remote" collection is on the right. This reduces the number of iterations from your six down to two, and produces the same output:

Customer.java

package com.stackexchange.ConsentExample;

import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public record Customer(
    Long id,
    String name,
    Integer consent
) {
    @Override
    public String toString() {
        return String.format(
            "Customer{id=%d, name='%s', consent=%d}",
            id, name, consent);
    }

    public static Stream<Customer> join(
        Collection<Customer> locals,
        Collection<Customer> remotes
    ) {
        /* Take local consent if there is no matching remote consent.
           Take remote consent if there is a match. */
        Map<Integer, Customer> remoteByConsent =
            remotes.stream()
            .collect(Collectors.toMap(
                Customer::consent, Function.identity()
            ));

        return locals.stream()
            .map(local ->
                remoteByConsent.getOrDefault(local.consent, local)
            );
    }
}

JoinTest.java

import com.stackexchange.ConsentExample.Customer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class JoinTest {
    @Test
    public void testJoin() {
        final List<Customer>
        remotes = List.of(
            new Customer(10L, "name1", 12),
            new Customer(11L, "name2", 11),
            new Customer(12L, "name3", 14),
            new Customer(13L, "name4", 16)
        ),
        locals = List.of(
            new Customer(1L, "name1", 12),
            new Customer(2L, "name2", 13),
            new Customer(3L, "name3", 14),
            new Customer(4L, "name4", 15)
        );
        Map<Long, Customer> result =
            Customer.join(locals, remotes)
            .collect(Collectors.toMap(
                Customer::id, Function.identity()
            ));

        assertEquals(4, result.size());

        assertEquals("name1", result.get(10L).name());
        assertEquals(12, result.get(10L).consent());
        assertEquals("name2", result.get(2L).name());
        assertEquals(13, result.get(2L).consent());
        assertEquals("name3", result.get(12L).name());
        assertEquals(14, result.get(12L).consent());
        assertEquals("name4", result.get(4L).name());
        assertEquals(15, result.get(4L).consent());
    }
}
🌐
Baeldung
baeldung.com › home › java › java list › intersection of two lists in java
Intersection of Two Lists in Java | Baeldung
April 4, 2025 - Finally, we convert our output with a Collector. The intersection should contain each common element only once. The order shouldn’t matter, thus toSet is the most straightforward choice, but we can also use toList or another collector method. For more details, review our guide to Java 8’s Collectors.
Top answer
1 of 4
19

If I understand correctly, this is the example scenario:

  • listOne [datab] items: [A, B, C, D]
  • listTwo [front] items: [B, C, D, E, F]

and what you need to get as an effect is:

  • added: [E, F]
  • deleted: [A]

First thing first, I would use some type adapter or extend the different types from one common class and override the equals method so you can match them by id and name

Secondly, this is very easy operations on sets (you could use set's but list are fine too). I recommend using a library: https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html

And now basically:

  • added is listTwo - listOne
  • deleted is listOne - listTwo

and using java code:

  • added: CollectionUtils.removeAll(listTwo, listOne)
  • deleted: CollectionUtils.removeAll(listOne, listTwo)

Otherwise, all collections implementing Collection (Java Docs) also has removeAll method, which you can use.

2 of 4
18

I propose solution using java 8 streams:

    ArrayList<ObjOne> list = new ArrayList<>(Arrays.asList(new ObjOne("1","1"),new ObjOne("3","3"),new ObjOne("2","2")));
    ArrayList<ObjTwo> list2 = new ArrayList<>(Arrays.asList(new ObjTwo("1","1"),new ObjTwo("3","3"),new ObjTwo("4","4")));

    List<ObjOne> removed = list.stream().filter(o1 -> list2.stream().noneMatch(o2 -> o2.getId().equals(o1.getId())))
            .collect(Collectors.toList());
    System.out.print("added ");
    removed.forEach(System.out::println);

    List<ObjTwo> added = list2.stream().filter(o1 -> list.stream().noneMatch(o2 -> o2.getId().equals(o1.getId())))
             .collect(Collectors.toList());

    System.out.print("removed ");
    added.forEach(System.out::println);

This is basically your solution but implemented using streams, which will make your code shorter and easer to read