Difference Between Two Lists

In this article, we’ll introduce the method to find the differences between two lists in Java. There are a few different approaches, let’s go through them one by one.

Question

Supposing we have two lists where some elements are identical, one list contains the elements we already have while the other contains the elements from incoming request. we want to determine which elements are newly added and which elements should be removed.

oldList: a, b, c
newList: b, c, d
newlyAdded: [d], removed: [a]

Plain Java

There is no explict way to do this, but we can bypass it by usingremoveAll() method from List class to remove all common elements in the other list.

Note that removeAll() method will change the original list. Therefore, we need to create new List objects to hold the target data.

    private static void plainJava() {
        List<String> oldList = Arrays.asList("a", "b", "c");
        List<String> newList = Arrays.asList("b", "c", "d");
        List<String> newAdded = new ArrayList<>(newList);
        newAdded.removeAll(oldList);
        List<String> removed = new ArrayList<>(oldList);
        removed.removeAll(newList);
        log.info("newly added: {}, removed: {}", newAdded, removed);
    }

Java 8 Stream

Code gets more cleaner and readible when using Java Stream API.

    private static void javaStream() {
        List<String> oldList = Arrays.asList("a", "b", "c");
        List<String> newList = Arrays.asList("b", "c", "d");
        List<String> newAdded = newList.stream()
                .filter(e -> !oldList.contains(e)).collect(Collectors.toList());
        List<String> removed = oldList.stream()
                .filter(e -> !newList.contains(e)).collect(Collectors.toList());
        log.info("new added: {}, removed: {}", newAdded, removed);
    }

Apache Common Collections

If you have Apache common collections in the project classpath, ListUtils.removeAll() is another option to merge 2 lists.

ListUtils.removeAll() accepts two lists and return a new one, it won’t modify the original lists.

    private static void apacheCommonsCollectionsListUtils() {
        List<String> oldList = Arrays.asList("a", "b", "c");
        List<String> newList = Arrays.asList("b", "c", "d");
        List<String> newAdded = ListUtils.removeAll(newList, oldList);
        List<String> removed = ListUtils.removeAll(oldList, newList);
        log.info("newly added: {}, removed: {}", newAdded, removed);
    }

By the way, if you are working on Set, you can use SetUtils.difference()

    Set<String> newAdded = SetUtils.difference(newSet, oldSet);
    Set<String> removed = SetUtils.difference(oldSet, newSet);

Google Guava

There is not handy method in Guava to get difference between two lists, but there is method for Set class. To use guava, we need to first convert our List to a Set:

    private static void googleGuavaSetsDifference() {
        List<String> oldList = Arrays.asList("a", "b", "c");
        List<String> newList = Arrays.asList("b", "c", "d");
        Set<String> oldSet = Sets.newHashSet(oldList);
        Set<String> newSet = Sets.newHashSet(newList);
        Set<String> newAdded = Sets.difference(newSet, oldSet);
        Set<String> removed = Sets.difference(oldSet, newSet);
        log.info("newly added: {}, removed: {}", newAdded, removed);
    }

Read More