Compare two lists in Java using Comparator
DZone > Java Zone > How to Compare List Objects in Java 7 vs. Java 8 How to Compare List Objects in Java 7 vs. Java 8In this blast from the not-too-distant past, we compare how Java 8's Stream API changed how you can compare List objects. by Jun. 01, 18 · Java Zone · TutorialArpan Das ·Like (12) Comment Save Tweet 258.16K Views Join the DZone community and get the full member experience. Show
Comparing the content of Lists against some condition is a common use case to handle in many business scenarios. This comparison can be broadly classified as:
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. package com.tuturself; import java.util.Arrays; import java.util.List; public class ListCompare { public static void main(String[] args) { List < Integer > aList = Arrays.asList(new Integer[] { 1, 3, 5, 6, 8 }); List < Integer > bList = Arrays.asList(new Integer[] { 10, 89, 8, 9 }); for (Integer i: aList) { if (bList.contains(i)) { System.out.println("Match Found " + i); break; } } } }Now let us develop all the above use cases in Java 8. The Java 8 Stream API provides threemethods allMatch, anyMatch, and noneMatch, which can be applied to a stream object that matches the given Predicate and then returns a boolean value. It is recommended to check the following articles if you are not familiar with the Stream API.
What Is Matching in the Context of Streams?Given a stream of objects, many-a-times, we need to check whether objects in the given stream match some specific criteria. Instead of writing logic for iterating over the stream elements and checking whether each object matches the criteria, Java 8 Streams allow declarative matching of objects in the stream. We need to define a Predicate instance with the comparison logic and provide this Predicate as an input to the matching methods. Then, Java 8 processes the matching function internally and provides you with the result whether a match for the condition was found or not. Stream.allMatch: We pass the Predicate as an argument to theallMatch() method. That Predicate is applied to each element of the stream, and if each and every element satisfies the given Predicate, then it returns true otherwise false. Stream.anyMatch: For theanyMatch() method, we pass the Predicate as an argument. The element of the stream is iterated for this Predicate. If any element matches, then it returns true otherwise false. Stream.noneMatch: ThenoneMatch() method is a method that takes an argument as a Predicate, and if none of the elements of the stream matches the given Predicate, then it returns true otherwise false. Now let us check some examples of these methods. We will have a simple model class,Employee, for all our examples: package com.tuturself.stream; public class Employee { private int id; private String name; private int age; private int salary; public Employee(int id, String name, int age, int salary) { super(); this.id = id; this.name = name; this.age = age; this.salary = salary; } public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public int getSalary() { return salary; } }Now we will define some predicates for checking some conditions that will be used in these methods. package com.tuturself.stream; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; public class EmployeePredicates { public static Predicate < Employee > isAdult() { return p - > p.getAge() > StreamTest.ADULT; } public static Predicate < Employee > isSalaryMoreThan(Integer salary) { return p - > p.getSalary() > salary; } public static List < Employee > filterAndGetEmployees(List < Employee > employees, Predicate < Employee > predicate) { return employees.stream().filter(predicate) .collect(Collectors. < Employee > toList()); } }Now consider the following test cases for all these methods. package com.tuturself.stream; import java.util.ArrayList; import java.util.List; public class StreamTest { public static int ADULT = 18; public static List < Employee > getEmployeeList() { List < Employee > employeeList = new ArrayList < > (); employeeList.add(new Employee(1, "Ninja Panda", 32, 200)); employeeList.add(new Employee(2, "Maste Shifu", 36, 250)); employeeList.add(new Employee(3, "Aidan Lloyd", 22, 300)); employeeList.add(new Employee(4, "Aidan Lloyd", 34, 700)); employeeList.add(new Employee(5, "PandaLuca Gallagher", 30, 1200)); return employeeList; } public static void main(String[] args) { List < Employee > employeeList = getEmployeeList(); // is all employees are Adult. System.out.println("Are all employees are adult: " + employeeList.stream().allMatch(EmployeePredicates.isAdult())); // is there is an employee whose salary is more than 1000 System.out.println("Has employee with more than 1000 salary: " + employeeList.stream() .anyMatch(EmployeePredicates.isSalaryMoreThan(1000))); // is there is an employee whose salary is more than 1000 System.out.println("Has employee with more than 1500 salary: " + employeeList.stream() .anyMatch(EmployeePredicates.isSalaryMoreThan(1500))); // do we have an employee named Andy System.out.println("We do not have an employee named Andy: " + employeeList.stream() .noneMatch(e - > e.getName().contains("Andy"))); } }So, the predicates can be defined externally as defined in theEmployeePredicates class or can be provided in these methods itself, as we did for the noneMatch() method. The Predicate is provided as e-> e.getName().contains("Andy"). The output of the program is: Are all employees are adult: true Has employee with more than 1000 salary: true Has employee with more than 1500 salary: false We do not have an employee named Andy: trueWe can collect all the elements matching the given Predicate to some Collection. Check the following method from the EmployeePredicatesclass. public static List < Employee > filterAndGetEmployees(List < Employee > employees, Predicate < Employee > predicate) { return employees.stream().filter(predicate).collect(Collectors. < Employee > toList()); }Let us collect and print the names of all the Employees earning more than 300. ListThe output of the program is: Aidan Lloyd PandaLuca GallagherCompare Two Lists by These Matching Methods?Now let us come back to the earlier program, where we were comparing twoLists' content with Java 7. Let us rewrite the program in Java 8 using these matching methods. package com.tuturself; import java.util.Arrays; import java.util.List; public class ListCompare { public static void main(String[] args) { List < Integer > aList = Arrays.asList(new Integer[] { 1, 3, 5, 6, 8 }); List < Integer > bList = Arrays.asList(new Integer[] { 10, 89, 8, 9 }); // If any number from List is present in List 2 System.out.println( "If any number from aList is present in List 2 :" + aList.stream().anyMatch(num - > bList.contains(num))); // If any number from List is present in List 2 System.out.println( "If any number from aList is not present in List 2 :" + aList.stream().noneMatch(num - > bList.contains(num))); // If any number from List is present in List 2 System.out.println( "If all numbers from aList are present in List 2 :" + aList.stream().allMatch(num - > bList.contains(num))); } }Now, the output of the program is: If any number from aList is present in List 2 :true If any number from aList is not present in List 2 :false If all numbers from aList are present in List 2 :trueIf you enjoyed this article and want to learn more about Java Streams, check out this collection of tutorials and articleson all things Java Streams. Topics: java, java 7, java 8, lists, comparing objects, tutorial Published at DZone with permission of Arpan Das. See the original article here. Opinions expressed by DZone contributors are their own. Popular on DZone
Comments Java Partner Resources |