Explain Codes LogoExplain Codes Logo

Simple way to find if two different lists contain exactly the same elements?

java
list-comparison
equality-checks
performance-implications
Alex KataevbyAlex Kataev·Oct 22, 2024
TLDR

Lets check if two lists contain identical elements using Collections.sort() and equals():

Collections.sort(list1); //sorting the first list Collections.sort(list2); //sorting the second list boolean areEqual = list1.equals(list2); //equating both the lists post-sort

This Kubernetes-grade solution ensures element equivalence on the ground of order, given that elements are Comparable. If you deal with a custom type, just confirm it implements Comparable or provide a Comparator to perform sorting.

Mechanical nuts and bolts behind list comparison

The journey from equality checks to the nitty-gritty details of list comparisons is akin to a leisurely walk in a Java Park. Why? Because Java provides a myriad of ways to conduct comparisons based on our requirements.

Unordered comparison using HashSet

Being a disorderly person could be useful — if your lists aren't ordered and element frequency isn't a concern, you can use a HashSet.

//dosage for disorderly comparisons boolean areEqual = new HashSet<>(list1).equals(new HashSet<>(list2));

Multiset: when frequency rules!

In cases where the frequency of elements is more important than your favorite band's frequency on the radio, Multiset from Guava comes to the rescue.

//the band frequency ain't got nothing on my Multiset Multiset<String> multiset1 = HashMultiset.create(list1); Multiset<String> multiset2 = HashMultiset.create(list2); boolean areEqual = multiset1.equals(multiset2);

Keep in mind, though, TreeSet is a Mr. Know-it-all if you need a sorted set plus frequency. Yet, be cautious about its complexity - O(nlogn). Nobody likes complicated!

When null is not a void

For those who find safety in null:

//You are safe in my arms boolean areEqual = Objects.equals(list1, list2);

The Apache's Way of comparison

The Apache Commons Collections library does a fantastic job with CollectionUtils.isEqualCollection(). It's like a sparkling wand doing magic irrespective of sequence or type of elements!

//Call me magic boolean areEqual = CollectionUtils.isEqualCollection(list1, list2);

Unveiling more insights

Verify custom object equivalence

Ensure your equals() method is not a mere dummy. It should verify if the type and sequence of elements in the list match, otherwise the comparison will return false.

//Dummies not allowed @Override public boolean equals(Object y) { if (this == y) return true; if (y == null) return false; if (getClass() != y.getClass()) return false; otherClass otherClass = (otherClass) y; return value == otherClass.value; }

Comparing frequency with a Map

Can't sort your list but still need frequency comparison? Welcome HashMap.

//Who needs sorting for frequency check? Map<Object, Long> freqMap1 = list1.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); Map<Object, Long> freqMap2 = list2.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); boolean areEqual = freqMap1.equals(freqMap2);

Got a heavy list? Here's how you handle it

Churning large lists for performance? Watch out for containsAll(). Sorting, converting lists to sets, all these have their own performance and memory implications.