Before beginning, I think that this question has a very simple answer that I'm just overlooking. I figured a few more eyes on the question at hand will be able to point out my problem fairly quickly.
I have two ArrayLists that I want to compare and remove duplicates from each of them. The first ArrayList is an ArrayList of older information where as the second ArrayList contains the new information.
Like so
ArrayList<Person> contactList = new ArrayList();
contactList.add(new Person("Bob");
contactList.add(new Person("Jake");
contactList.add(new Person("Joe");
ontactList.add(new Person("Rob");
ArrayList<Person> updatedContactList = new ArrayList();
updatedContactList.add(new Person("Bob");
updatedContactList.add(new Person("Jake");
updatedContactList.add(new Person("Joe");
updatedContactList.add(new Person("Phil");
My Person class is very simple, created solely for this example
public class Person {
private String name;
public Person(String a_name) {
name = a_name;
}
public String getName() {
return name;
}
}
So, using the above examples, I want to remove all duplicates. I'm trying keep it to just the two ArrayLists if possible, but am willing to do a deep clone of one of the ArrayLists if I have to.
So I want the resulting ArrayList to have the following information in it once the comparison is done
contactList //removed Person
- Rob
updatedContactList //new Person
- Phil
Here is the code I've put together
for(int i = 0; i < contactList.size(); i++) {
for(int j = 0; j < updatedContactList.size(); j++) {
if(contactList.get(i).getName().equals(updatedContactList.get(j).getName())) {
//removed friends
contactList.remove(contactList.get(i));
//new friends ---- only one at a time works
//updatedContactList.remove(updatedContactList.get(j));
}
}
}
I'm only able to remove a Person from one of the ArrayLists in the above loop otherwise I get incorrect results.
So my question is, is there an easy way to remove the duplicated elements from both ArrayLists? If so, how do I go about it.
I realize that I could probably deep clone the updated ArrayList and just remove the objects from that one, but I'm wondering if there is a way without having to clone it.
I also realize that I could just stuff all the elements into a Set and it would remove the duplicates, but I want to keep the 'removed' and 'new' Person objects separate.
Duplicates : ArrayList allows duplicate values while HashSet doesn't allow duplicates values. Ordering : ArrayList maintains the order of the object in which they are inserted while HashSet is an unordered collection and doesn't maintain any order.
What you really have is not lists, but sets: model both the old and the new contacts as a Set. Also implement equals and hashCode for your Person class to ensure proper operation.
Once you have that, you'll be able to write one-liners to calculate the set differences (which is what you need):
final Set<Person> contactsBackup = new HashSet<>(contacts);
contacts.removeAll(updatedContacts);
updatedContacts.removeAll(contactsBackup);
Note that this involves making one more copy, but it is not a deep copy—only references are copied. This is a very leightweight operation and you should not worry about its impact.
If, for some reason not at all obvious to me, you really need lists, the same code will work for them, too (List also defines removeAll), but you will have to live with O(n2) complexity this operation entails for lists.
Override equals() and hashCode() in your Person class and simply do:
Set<Person> temp = new HashSet<>(contactList);
contactList.removeAll(updatedContactList);
updatedContactList.removeAll(temp);
temp.clear(); // not necessary if this code is in a method
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With