views:

246

answers:

3

Hello everyone, I have a scenario in my code where I need to compare two Lists and remove from the first list, objects which are present in the second list. Akin to how the "removeAll" object works for List. Since my List is created on a custom object, the removeAll method won't work for me.

I have tried various methods to make this work: - implemented equals() and hashCode for the custom object comprising the list - implemented the Comparable Interface for the custom object - implemented the Comparator Interface for the custom object

I've even tried using the Apache Common's CollectionUtils and ListUtils methods (subtract, intersect, removeAll). None seem to work.

I understand I will perhaps need to write some custom removal code. But not sure how to go about doing that. Any pointers helping me move in the right direction will be really appreciated.

Thanks, Jay

+5  A: 

Java Collections already cater for your scenario. Call Collection.removeAll(Collection) and it'll remove all the items from the passed in collection using the equals() method to test for equality.

List<String> list1 = new ArrayList<String>();
Collections.addAll(list1, "one", "two", "three", "four");
List<String> list2 = new ArrayList<String>();
Collections.addAll(list2, "three", "four", "five");
list1.removeAll(list2); // now contains "one", "two"

To make this work the objects you're storing just need to properly implement the equals/hashCode contract, which is: given any two objects a and b:

a.equals(b) == b.equals(a)

and:

a.hashCode() == b.hashCode() if a.equals(b)

Improperly defined equals and hashCode methods create undefined behaviour and are the common cause of collections related issues.

cletus
@Cletus: he actually says (a little below) that he tried and it didn't work for him.
Roman
@Roman until he posts some code I don't believe it. More than likely it will come down to something like incorrect use of the API or violating the equals/hashCode contract, etc.
cletus
+2  A: 

Overriding equals and hashCode methods is enough to make method removeAll work on custom objects.

It's likely that you didn't override them in a proper way. Some code will help us a lot.

Roman
+4  A: 

You said:

... Since my List is created on a custom object, the removeAll method won't work for me.

As others have stated, .removeAll() should work for the scenario you described, even for custom objects, as long as the custom objects obey the contracts that Java Collections expects of its objects, including a properly implement equals() and hashCode() method.

I have tried various methods to make this work: - implemented equals() and hashCode for the custom object comprising the list - implemented the Comparable Interface for the custom object - implemented the Comparator Interface for the custom object ...

It sounds like your are shot-gunning different approaches: coding one, trying it, quickly coding another, trying it, coding yet another, ... It make be worthwhile to slow down and try to understand why each approach failed and/or determine why that approach won't work for your situation, before moving on to the next. If you've already investigated and determined why each approach won't work, please explain in your question. If you haven't, then let us help by posting code.

Since most people agree the first approach (.removeall()) should have work and since custom objects are involved, why not take a quick review of this StackOverflow question to see if anything jumps out of you:

Overriding equals and hashCode in Java

"What issues / pitfalls do I need to consider when overriding equals and hashCode in a java class?"

Bert F