Skip to content
Advertisement

How do I remove duplicate objects from two separate ArrayLists?

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.

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement