How to remove duplicate objects from two separate ArrayLists?

Before starting, I think this question has a very simple answer, which I simply ignore. I thought that a few more eyes on the question at hand would be able to point out my problem pretty quickly.

I have two lists of ArrayLists that I want to compare and remove duplicates from each of them. The first ArrayList is the ArrayList older information, where the second ArrayList contains the new information.

In this way

 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 just 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 examples above, I want to remove all duplicates. I try to save it in only two ArrayLists, if possible, but I am ready to make a deep clone of one of the ArrayLists, if I need to.

So, I want the resulting ArrayList have the following information in it after comparison

 contactList //removed Person - Rob updatedContactList //new Person - Phil 

Here is the code I compiled

 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 can remove Person from one of the ArrayLists in the above loop, otherwise I get the wrong results.

So my question is, is there an easy way to remove duplicate elements from both ArrayLists? If so, how do I do this.

I understand that I could probably deeply clone the updated ArrayList and just remove objects from this, but I wonder if there is a way without cloning it.

I also understand that I could just fill all the elements in Set and it will remove duplicates, but I want individual Person objects to be deleted.

+6
source share
5 answers

What you really have is not lists, but sets: model both old and new contacts as Set . Also use equals and hashCode for your Person class to ensure proper operation.

Once you do this, you can write single-line expressions to calculate the set differences (what you need):

 final Set<Person> contactsBackup = new HashSet<>(contacts); contacts.removeAll(updatedContacts); updatedContacts.removeAll(contactsBackup); 

Please note that this includes creating another copy, but this is not a deep copy, only links are copied. This is a very easy operation, and you should not worry about its effect.

If for some reason it’s completely not obvious to me, you really need lists, the same code will work for them ( List also defines removeAll ), but you have to live with O (n 2 ), that this operation entails lists .

+6
source

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 
+3
source

Create Set and addAll as from ArrayLists .

 Set<Person> set = new ArrayList<Person>(); 

http://docs.oracle.com/javase/6/docs/api/java/util/Set.html

+2
source

In this case, use Set, not List (this is used if you get data from the database using, for example, Hibernate), if possible. Then you can override the equals and hashcode method in the person class so that when you add the necessary comparisons, you can make and duplicates can be removed. LinkedHashSet can be used because lists can slow down as data grows.

+1
source

This is a one-line, elegant solution using Java 8 features.

 public static final <T> void removeCommonEntries(Collection<T> a, Collection<T> b){ b.removeIf(i -> a.remove(i)); } 

I put this solution in your custom CollectionUtils .

0
source

Source: https://habr.com/ru/post/946439/


All Articles