Java Compare Two List's object values?
JavaListArraylistJava Problem Overview
I have two list *ListA<MyData> listA = new ArrayList<MyData>()
* and ListB<MyData> listB = new ArrayList<MyData>()
both contain object of type MyData and MyData contain these variables.
MyData {
String name;
boolean check;
}
ListA and ListB both contains MyData objects ,now I have to compare both the list's object values here name as well check variable like if ListA contains these object values
ListA = ["Ram",true],["Hariom",true],["Shiv",true];
and ListB also contain
ListB = ["Ram",true],["Hariom",true],["Shiv",true];
then i have to compare lists and return false because both list are same But if ListA contains
ListA = ["Ram",true],["Hariom",true],["Shiv",false];
and ListB Contain
ListB = ["Ram",true],["Hariom",true],["Shiv",true];
then I have to compare lists and return true because both list are not same
or vice-versa so any slight change in the any list values I have to return true. One thing I have to mentioned here objects can be in any order.
Java Solutions
Solution 1 - Java
It's not the most efficient solution but the most terse code would be:
boolean equalLists = listA.size() == listB.size() && listA.containsAll(listB);
Update:
@WesleyPorter is right. The solution above will not work if duplicate objects are in the collection.
For a complete solution you need to iterate over a collection so duplicate objects are handled correctly.
private static boolean cmp( List<?> l1, List<?> l2 ) {
// make a copy of the list so the original list is not changed, and remove() is supported
ArrayList<?> cp = new ArrayList<>( l1 );
for ( Object o : l2 ) {
if ( !cp.remove( o ) ) {
return false;
}
}
return cp.isEmpty();
}
Update 28-Oct-2014:
@RoeeGavriel is right. The return statement needs to be conditional. The code above is updated.
Solution 2 - Java
ArrayList
already have support for this, with the equals
method. Quoting the docs
> ... > In other words, two lists are defined to be equal if they contain the same elements in the same order.
It does require you to properly implement equals
in your MyData
class.
Edit
You have updated the question stating that the lists could have different orders. In that case, sort your list first, and then apply equals.
Solution 3 - Java
I got this solution for above problem
public boolean compareLists(List<MyData> prevList, List<MyData> modelList) {
if (prevList.size() == modelList.size()) {
for (MyData modelListdata : modelList) {
for (MyData prevListdata : prevList) {
if (prevListdata.getName().equals(modelListdata.getName())
&& prevListdata.isCheck() != modelListdata.isCheck()) {
return true;
}
}
}
}
else{
return true;
}
return false;
}
EDITED:-
How can we cover this...
Imagine if you had two arrays "A",true "B",true "C",true and "A",true "B",true "D",true. Even though array one has C and array two has D there's no check that will catch that(Mentioned by @Patashu)..SO for that i have made below changes.
public boolean compareLists(List<MyData> prevList, List<MyData> modelList) {
if (prevList!= null && modelList!=null && prevList.size() == modelList.size()) {
boolean indicator = false;
for (MyData modelListdata : modelList) {
for (MyData prevListdata : prevList) {
if (prevListdata.getName().equals(modelListdata.getName())
&& prevListdata.isCheck() != modelListdata.isCheck()) {
return true;
}
if (modelListdata.getName().equals(prevListdata.getName())) {
indicator = false;
break;
} else
indicator = true;
}
}
}
if (indicator)
return true;
}
}
else{
return true;
}
return false;
}
Solution 4 - Java
First, implement the MyData.equals(Object o)
and MyData.hashCode()
methods.
Once you implemented the equals
method, you can iterate over the lists as follows:
if(ListA == null && ListB == null)
return false;
if(ListA == null && ListB != null)
return true;
if(ListA != null && ListB == null)
return true;
int max = ListA.size() > ListB.size() ? ListA.size() : ListB.size();
for(int i = 0; i < max; i++) {
myData1 = ListA.get(i);
myData2 = ListB.get(i);
if(!myData1.equals(myData2)) {
return true;
}
}
return false;
Solution 5 - Java
I found a very basic example of List comparison at List Compare This example verifies the size first and then checks the availability of the particular element of one list in another.
Solution 6 - Java
Override the equals method in your class and use Collection#equals() method to check for equality.
Solution 7 - Java
You can subtract one list from the other using CollectionUtils.subtract, if the result is an empty collection, it means both lists are the same. Another approach is using CollectionUtils.isSubCollection or CollectionUtils.isProperSubCollection.
For any case you should implement equals and hashCode methods for your object.
Solution 8 - Java
Using java 8 removeIf to compare similar items
public int getSimilarItems(){
List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
int initial = two.size();
two.removeIf(one::contains);
return initial - two.size();
}
Solution 9 - Java
This can be done easily through Java8 using forEach and removeIf method.
Take two lists. Iterate from listA and compare elements inside listB
Write any condition inside removeIf method.
Hope this will help
listToCompareFrom.forEach(entity -> listToRemoveFrom.removeIf(x -> x.contains(entity)));
Solution 10 - Java
Logic should be something like:
-
First step: For class MyData implements Comparable interface, override the compareTo method as per the per object requirement.
-
Second step: When it comes to list comparison (after checking for nulls), 2.1 Check the size of both lists, if equal returns true else return false, continue to object iteration 2.2 If step 2.1 returns true, iterate over elements from both lists and invoke something like,
listA.get(i).compareTo(listB.get(i))
This will be as per the code mentioned in step-1.
Solution 11 - Java
See if this works.
import java.util.ArrayList;
import java.util.List;
public class ArrayListComparison {
public static void main(String[] args) {
List<MyData> list1 = new ArrayList<MyData>();
list1.add(new MyData("Ram", true));
list1.add(new MyData("Hariom", true));
list1.add(new MyData("Shiv", true));
// list1.add(new MyData("Shiv", false));
List<MyData> list2 = new ArrayList<MyData>();
list2.add(new MyData("Ram", true));
list2.add(new MyData("Hariom", true));
list2.add(new MyData("Shiv", true));
System.out.println("Lists are equal:" + listEquals(list1, list2));
}
private static boolean listEquals(List<MyData> list1, List<MyData> list2) {
if(list1.size() != list2.size())
return true;
for (MyData myData : list1) {
if(!list2.contains(myData))
return true;
}
return false;
}
}
class MyData{
String name;
boolean check;
public MyData(String name, boolean check) {
super();
this.name = name;
this.check = check;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (check ? 1231 : 1237);
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyData other = (MyData) obj;
if (check != other.check)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Solution 12 - Java
It's been about 5 years since then and luckily we have Kotlin now.
Comparing of two lists now looks is as simple as:
fun areListsEqual(list1 : List<Any>, list2 : List<Any>) : Boolean {
return list1 == list2
}
Or just feel free to omit it at all and use equality operator.
Solution 13 - Java
I know it's old question but in case anyone needs it. I use this in my application and it works well. i used it to check if the cart has been changed or not.
private boolean validateOrderProducts(Cart cart) {
boolean doesProductsChanged = false;
if (originalProductsList.size() == cart.getCartItemsList().size()) {
for (Product originalProduct : originalProductsList) {
if (!doesProductsChanged) {
for (Product cartProduct : cart.getCartProducts()) {
if (originalProduct.getId() == cartProduct.getId()) {
if (originalProduct.getPivot().getProductCount() != cartProduct.getCount()) {
doesProductsChanged = true;
// cart has been changed -> break from inner loop
break;
}
} else {
doesProductsChanged = false;
}
}
} else {
// cart is already changed -> break from first loop
break;
}
}
} else {
// some products has been added or removed (simplest case of Change)
return true;
}
return doesProductsChanged;
}
Solution 14 - Java
String myData1 = list1.toString();
String myData2 = list2.toString()
return myData1.equals(myData2);
where :
list1 - List<MyData>
list2 - List<MyData>
Comparing the String worked for me. Also NOTE I had overridden toString() method in MyData class.
Solution 15 - Java
I think you can sort both lists and convert to List if some of them was a HashSet colleciton.
java.utils.Collections package lets you do it.
List<Category> categoriesList = new ArrayList<>();
Set<Category> setList = new HashSet<>();
Collections.sort(categoriesList);
List<Category> fileCategories = new ArrayList<>(setList);
Collections.sort(fileCategories);
if(categoriesList.size() == fileCategories.size() && categoriesList.containsAll(fileCategories)) {
//Do something
}