Backend Development 7 min read

Comparing Two Lists and Extracting Differences Using Java 8 Stream API

This article demonstrates four Java 8 Stream API techniques for comparing two List collections and retrieving the elements that differ, including simple filtering, concatenation, grouping by occurrence, and attribute‑based comparison with custom DTOs.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Comparing Two Lists and Extracting Differences Using Java 8 Stream API

You can use Java 8's Stream API to compare two List objects and extract the differing elements.

Method 1

Steps: convert both lists to streams, use filter to keep items not present in the other list, then collect the results back into a List.

List
list1 = Arrays.asList("A", "B", "C", "D");
List
list2 = Arrays.asList("B", "C", "E", "F", "A", "D");
List
diff = list1.stream().filter(item -> !list2.contains(item)).collect(Collectors.toList());
List
diff1 = list2.stream().filter(item -> !list1.contains(item)).collect(Collectors.toList());
diff.addAll(diff1);

diff.forEach(x -> System.out.println(x));

The code converts the two lists to streams, filters out the common elements, collects the unique ones into a new list, and prints the result.

Method 2

Steps: use Stream.concat to merge the filtered streams from both lists into a single stream and collect the distinct elements.

List
list1 = Arrays.asList("apple", "banana", "orange", "pear");
List
list2 = Arrays.asList("apple", "banana", "grape");

List
list3 = Stream.concat(
        list1.stream().filter(str -> !list2.contains(str)),
        list2.stream().filter(str -> !list1.contains(str)))
        .collect(Collectors.toList());

System.out.println("Different strings: " + list3);

This approach defines two lists, filters each list for elements not present in the other, concatenates the two filtered streams, and collects the result into list3 , which is then printed.

Method 3

Steps: merge the two lists with Stream.concat , then use Collectors.groupingBy together with Collectors.counting to count occurrences of each object; finally filter for objects that appear only once.

List
l1 = new ArrayList<>();
l1.add(new Object(1, "a"));
l1.add(new Object(2, "b"));
l1.add(new Object(3, "c"));

List
l2 = new ArrayList<>();
l2.add(new Object(1, "a"));
l2.add(new Object(3, "c"));
l2.add(new Object(4, "d"));

List
resultList = Stream.concat(l1.stream(), l2.stream())
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
        .entrySet().stream()
        .filter(e -> e.getValue() == 1)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());

This method requires the element class to correctly implement equals and hashCode so that the stream can compare objects; it works for built‑in types or properly defined custom types.

Method 4

Steps: compare two lists of ProductAttributeNameDTO objects by their name property, using Stream.concat and grouping to find attribute names that appear only once, then retrieve the corresponding DTO objects.

List
l1 = Arrays.asList(
        new ProductAttributeNameDTO(1L, "颜色"),
        new ProductAttributeNameDTO(2L, "尺码"),
        new ProductAttributeNameDTO(3L, "重量")
);
List
l2 = Arrays.asList(
        new ProductAttributeNameDTO(1L, "颜色"),
        new ProductAttributeNameDTO(3L, "重量"),
        new ProductAttributeNameDTO(4L, "材质")
);

List
resultList = Stream.concat(l1.stream(), l2.stream())
        .collect(Collectors.groupingBy(ProductAttributeNameDTO::getName, Collectors.counting()))
        .entrySet().stream()
        .filter(e -> e.getValue() == 1)
        .map(e -> e.getKey())
        .map(name -> Stream.concat(l1.stream(), l2.stream()).filter(p -> p.getName().equals(name)).findFirst().get())
        .collect(Collectors.toList());

As with the previous method, the DTO class must implement equals and hashCode correctly; this technique is suitable when the list contains objects of the same DTO type.

Source: blog.csdn.net/Ascend1977/article/details/130131304

Backend Exclusive Technical Group

Build a high‑quality technical community; developers, recruiting HRs, and anyone willing to share job referrals are welcome.

Maintain civility: focus on technical exchange , job referrals , and industry discussion .

Advertisements are prohibited; beware of private messages and scams.

JavaFunctional ProgrammingCollectionsStream APIJava 8List comparison
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.