You can convert them to Set collections, and perform a set difference operation on them.

Like this:

Set<Date> ad = new HashSet<Date>(a);
Set<Date> bd = new HashSet<Date>(b);
ad.removeAll(bd);
Answer from Pablo Santa Cruz on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › java list › finding the differences between two lists in java
Finding the Differences Between Two Lists in Java | Baeldung
April 29, 2026 - List<String> differences = new ArrayList<>(listTwo); differences.removeAll(listOne); assertEquals(3, differences.size()); assertThat(differences).containsExactly("Daniel", "Alan", "George"); We should also note that if we want to find the common elements between the two lists, List also contains a retainAll method. A Java Stream can be used for performing sequential operations on data from collections, which includes filtering the differences between lists:
🌐
How to do in Java
howtodoinjava.com › home › collections framework › java arraylist › compare two lists in java: equality, differences, common items
Compare Two Lists in Java: Equality, Differences, Common Items
1 week ago - The article on asserting two lists are equal ignoring order compares these matchers with the plain JUnit options and shows their failure messages. The additional items are the elements of the first list that the second list does not contain, which is the set difference first – second.
🌐
amitph
amitph.com › home › java › finding the difference between two java lists
Finding the Difference Between Two Java Lists - amitph
November 22, 2024 - Set<String> differences = Sets ... language: Java (java) The difference method returns an instance of a Set containing the elements that exist only in the first instance and not in the other....
🌐
DevQA
devqa.io › java-compare-two-arraylists
Java Compare Two Lists
March 17, 2020 - To compare two lists for equality just in terms of items regardless of their location, we need to use the sort() method from the Collections() class. ... import java.util.Arrays; import java.util.Collections; import java.util.List; public class ...
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

🌐
Techie Delight
techiedelight.com › home › java › calculate difference between two lists in java
Calculate difference between two Lists in Java | Techie Delight
July 7, 2026 - We can use it to calculate differences between two lists, as follows. To avoid modifications to the original list, create a copy of the first list before calling the removeAll() method. ... The following solution transforms the List into a Set and calls the removeAll() method on it. ... In Java 8 and above, you can create a stream from the elements of the first list, and then filter the elements that are missing in the other list using the contains() method.
Top answer
1 of 7
2

Using Java 8 streams:

Logic Here:

I have used the java 8 stream operation to get the difference between two given lists and created a output message using StringBuilder as mentioned in the problem statement.

Code:

public class Test {
    public static void main(String[] args) {
        // Case 1
        List<String> order1 = Arrays.asList("A", "B");
        List<String> sended1 = Arrays.asList("A", "B");
        System.out.println("Case 1: " + getMissingItems(order1,sended1));

        // Case 2
        List<String> order2 = Arrays.asList("A", "B", "C");
        List<String> sended2 = Arrays.asList("B", "C");
        System.out.println("Case 2: " + getMissingItems(order2,sended2));

        // Case 3
        List<String> order3 = Arrays.asList("A", "D");
        List<String> sended3 = Arrays.asList("A", "B", "C", "D");
        System.out.println("Case 3: " + getMissingItems(order3,sended3));

        // Case 4
        List<String> order4 = Arrays.asList("A", "D", "F");
        List<String> sended4 = Arrays.asList("A", "B", "C", "D");
        System.out.println("Case 4: " + getMissingItems(order4,sended4));
    }

    private static String getMissingItems(List<String> order, 
                                          List<String> sended){
        StringBuilder sb = new StringBuilder();
        List<String> missingInOrder = getMissingInList(order, sended);
        createMessage(sb, missingInOrder," item(s) missing in order: ");
        List<String> missingInSended = getMissingInList(sended, order);
        if(!missingInOrder.isEmpty() && !missingInSended.isEmpty()){
            sb.append(" && ");
        }
        createMessage(sb, missingInSended," item(s) missing in sended: ");
        return sb.isEmpty() ? "No difference":sb.toString();
    }

    private static void createMessage(StringBuilder sb, 
                                      List<String> diffInList,
                                      String msg) {
        if(!diffInList.isEmpty()){
            sb.append(diffInList.size())
              .append(msg)
              .append(String.join(",", diffInList));
        }
    }

    private static List<String> getMissingInList(List<String> list1, 
                                                 List<String> list2) {
        return list2.stream()
                    .filter(e -> !list1.contains(e))
                    .collect(Collectors.toList());
    }
}

Output:

Case 1: No difference
Case 2: 1 item(s) missing in sended: A
Case 3: 2 item(s) missing in order: B,C
Case 4: 2 item(s) missing in order: B,C && 1 item(s) missing in sended:F
2 of 7
2

First, it's not clear enough if there are duplicates or not. Secondly, if you don't care about order then don't use the list equals() method as it will fail in many cases where both lists contains the same items but in different order.

Besides that, the algorithm should work but it could be optimized. I believe the main problem is that using the removeAll() method between a list of size n and a list of size m has a worst time complexity of O(n*m) (quadratic) when you could actually achieve a time complexity of O(n+m) (lineal). If you don't care about duplicates you could slightly modify your solution to use HashSet to achieve this goal in the following way:

// If duplicates are irrelevant
private static String getDifference(List<String> ordered, List<String> sent) {
    Set<String> orderedSet = new HashSet<>(ordered);
    Set<String> sentSet = new HashSet<>(sent);
    if (orderedSet.equals(sentSet)) {
        return "No difference";
    } else {
        StringBuilder output = new StringBuilder();
        orderedSet.removeAll(sent);

        if (!orderedSet.isEmpty()) {
            output.append(orderedSet.size()).append(" item(s) missing in sent: ");
            output.append("\"").append(String.join("\", \"", orderedSet)).append("\"");
        }

        sentSet.removeAll(ordered);

        if (!sentSet.isEmpty()) {
            if (output.length() > 0) {
                output.append(" & ");
            }

            output.append(sentSet.size()).append(" item(s) missing in ordered: ");
            output.append("\"").append(String.join("\", \"", sentSet)).append("\"");
        }

        return output.toString();
    }
}

If you care about duplicates then you aren't actually comparing Lists but Multisets. For a Multiset implementation you could use the Guava library. A possible implementation with Multisets looks like this:

// If duplicates are relevant, with Guava
private static String getDifferenceWithDuplicates(List<String> ordered, List<String> sent) {
    Multiset<String> orderedSet = HashMultiset.<String>create(ordered);
    Multiset<String> sentSet = HashMultiset.<String>create(sent);
    if (orderedSet.equals(sentSet)) {
        return "No difference";
    } else {
        StringBuilder output = new StringBuilder();

        for (String item : Sets.union(orderedSet.elementSet(), sentSet.elementSet())) {
            int orderedCount = orderedSet.count(item);
            int sentCount = sentSet.count(item);

            if (orderedCount != sentCount) {
                if (output.length() > 0) {
                    output.append(" & ");
                }

                output.append(Math.abs(orderedCount - sentCount)).append(" item(s) missing in ");
                output.append(orderedCount > sentCount ? "sent" : "ordered").append(": ");
                output.append("\"").append(item).append("\"");
            }
        }
        return output.toString();
    }
}

If for some reason you can't use Guava, then you can implement the same behavior of a HashMultiset using a HashMap of type Map<String, Integer> where the key is the item and the value is the amount of appearances in the original list (this is an exercise for the reader).

🌐
DevGenius
blog.devgenius.io › finding-the-differences-between-two-lists-in-java-the-complete-guide-6577f8a02c5b
Finding the Differences Between Two Lists in Java: The Complete Guide | by M Business Solutions | Dev Genius
December 5, 2024 - Validation: Ensuring that the data in two lists match or identifying discrepancies. Filtering: Removing or processing only the elements that differ between two lists.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › java › comparing-two-arraylist-in-java
Comparing two ArrayList In Java - GeeksforGeeks
January 23, 2026 - To compare two ArrayList objects, Java provides the equals() method. This method checks whether both lists have the same size and contain the same elements in the same order, making it a simple and reliable way to compare lists.
🌐
W3docs
w3docs.com › home › code snippets › java › java compare two lists
Java Compare Two Lists | W3docs
To compare two lists in Java, you can use the equals() method of the List interface.
🌐
Java Code Geeks
javacodegeeks.com › home › core java
Check If Two Lists Are Equal In Java - Java Code Geeks
March 20, 2019 - Lists in Java are ordered by nature. So, two lists are considered to be equal if they contain the exact same elements in the same order.
🌐
Coderanch
coderanch.com › t › 638779 › java › Compare-Contrast-ArrayList-Object
Compare and Contrast Two ArrayList<Object> (Java in General forum at Coderanch)
August 29, 2014 - Feel free to reference my mock ... versus java calculating it). It's impossible to check for changes since there is no unique key that can be compared across the two connectors. The difference function's purpose is not to find the changed objects, it's only for finding the added/removed ones. The changed objects are found by creating the two new lists and then comparing ...
🌐
Javatpoint
javatpoint.com › how-to-compare-two-arraylist-in-java
How to Compare Two ArrayList in Java - Javatpoint
How to Compare Two ArrayList in Java with oops, string, exceptions, multithreading, collections, jdbc, rmi, fundamentals, programs, swing, javafx, io streams, networking, sockets, classes, objects etc,
🌐
Medium
medium.com › @alxkm › how-to-find-intersection-and-difference-between-two-sets-or-lists-in-java-5a873a8bff5d
Java Interview: How to Find Intersection and Difference Between Two Sets or Lists in Java | by Alex Klimenko | Medium
August 9, 2025 - Set<String> diff = new HashSet<>(list1); diff.removeAll(list2); // Removes common elements System.out.println("Difference (list1 - list2): " + diff);
🌐
Stack Overflow
stackoverflow.com › questions › 49584587 › how-to-find-difference-between-two-lists
java - how to find difference between two lists - Stack Overflow
You cannot edit unmodifiableList as they are read-only. And in removeAll method, the elements of first lists which are in the second list are removed. So this operation can not be performed in NATURAL_MANDATORY. So if you must do it, then you can perhaps copy the elements to a new List and do this operation.
🌐
WeTalkIt
wetalkitorg.wordpress.com › 2020 › 02 › 03 › how-to-compare-two-lists-in-java
How to compare two Lists in Java - WeTalkIt - WordPress.com
February 25, 2020 - The first returns the list of all employers(intern and extern) per departement, another endpoint just returns the list of intern employers of a department. We will use two different methods two compare the both list and say, if in a department there are extern employees too. In this paragraph we will compare to list in java without the using of the Stream Api.
🌐
YouTube
youtube.com › naveen automationlabs
#7 - How to Compare Two ArrayLists in Java - YouTube
In this video, I have explained how to compare two ArrayLists in Java.Learn:1. Compare two ArrayList using Sort and Equals methods.2. Find out the additional...
Published: October 19, 2020
Views: 52K