How can I remove whats common to both lists based on an object attribute. Below I am trying to remove all values from testList2 that contain the same str1 parameter as testList1.
I think I can override the equals method in the class that is being compared as equals method is used under the hood when using removeAll ?
testList1 & testList2 are of type ArrayList and both contain a List of Test objects.
testList1.removeAll(testList2);
public class Test{
private String str1;
private String str2;
public Test(String str1 , String str2){
this.str1 = str1;
this.str2 = str2;
}
public String getStr1() {
return str1;
}
public String getStr2() {
return str2;
}
public boolean equals(Object o){
Test t = (Test)o;
return this.getStr1().equalsIgnoreCase(t.getStr2());
}
}
Yes, overriding
equals(...)should work withremoveAll(...), sinceArrayListwill use that for equality checks.Under the hood, the
removeAll(...)method inAbstractCollection(which is a super class ofArrayList) will callcontains(entry)on the collection that is passed toremoveAll(...).contains(...)inArrayListwill then get the index of the element usingindexOf(...)which in turn loops through all elements and callsequals(...)on those.That said, it becomes obvious that the
removeAll()implementation using lists has O(n2) complexity (loop through the source list and for each entry loop through the parameter list) which might get quite slow for bigger lists.Thus you might want to pass a set of the objects that you want removed to
removeAll(...). This would result in O(n * log(n)) complexity (the loop over the source list remains, but thecontainscall on a set is O(log(n)) only).