Alin
Alin

Reputation: 14571

Remove duplicate objects from a ArrayList in Android

I know this has be discussed over and over again here, but none of the examples I've tried worked for me.

What I've got

I access the Call log from Android and I get a list of all calls made. Of course, here I get a lot of duplicates. First I make a List

List<ContactObject> lstContacts = new ArrayList<ContactObject>();

Then I add objects into it

While (get some record in call log)
{
    ContactObject contact = new ContactObject();
    contact.SetAllProperties(......)  
    lstContacts.add(contact);  
}

Set<ContactObject> unique = new LinkedHashSet<ContactObject>(lstContacts);
lstContacts = new ArrayList<ContactObject>(unique);

The Contact Object class is simple

public class ContactObject {

    public ContactObject() {
        super();
    }

 @Override
 public boolean equals(Object obj) {
     if (!(obj instanceof ContactObject))
        return false;

     return this.lstPhones == ((ContactObject) obj).getLstPhones(); 
 }

 @Override
 public int hashCode() {
     return lstPhones.hashCode();
 }

    private long Id;
    private String name;
    private List<String> lstPhones;  
    private String details;

   //... getters and settres
}

What I need

I need to have a Contact only once in the list. As I've read around here there are a couple of things that can be done like Set, HashSet, TreeSet. TreeSet seems the best as it keeps the order just as I receive it from the Call log. I've tried to make my code work with it but no success. Could anyone be so kind to give me a sample code based on my example. Thank you for your time.

The Working Solution. Thank you all for your support, you've made my day.

In ContactObject override the two methods

 @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof ContactObject))
            return false;

         return lstPhones.equals(((ContactObject) obj).getLstPhones());
     }

     @Override
     public int hashCode() {
         return (lstPhones == null) ? 0 : lstPhones.hashCode();
     }

//Getters and Setters and COnstructor....

Simply use it as

Set<ContactObject> unique = new LinkedHashSet<ContactObject>(lstContacts);
lstContacts = new ArrayList<ContactObject>(unique);

Upvotes: 9

Views: 16993

Answers (5)

Muhammad Adil
Muhammad Adil

Reputation: 4668

Remove duplication of Custom Object

Example of Removing duplicate using Comparator

Lets suppose you have a class "Contact"

public class Contact implements Comparable<Contact> {


public String getName() {
    return this.Name;
}

public void setName(String name) {
    this.Name = name;
}

public String getNumber() {
    return this.Number;
}

public void setNumber(String number) {
    this.Number = number;
}


 ///// this method is very important you must have to implement it.
@Override
public String toString() {
    return "\n" +"Name=" + name + "   Number=" + Number;
}

Here is how you can remove duplicate entries using Set , just pass your list in the function and it will work for you. New list will be returned which will have no duplicated contacts.

 public ArrayList<Contact>  removeDuplicates(ArrayList<Contact> list){
    Set<Contact> set = new TreeSet(new Comparator<Contact>() {

        @Override
        public int compare(Contact o1, Contact o2) {
            if(o1.getNumber().equalsIgnoreCase(o2.getNumber())){
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);

    final ArrayList newList = new ArrayList(set);
    return newList;
}

It worked for me so please try and give me your feedback. Thanks

P.S: Credit goes to Nilanchala at this article

Upvotes: 9

everag
everag

Reputation: 7662

Use Set's instead.

Set's works as an Mathematical collection, so it doesn't allow duplicated elements.

So it checks the equality and the .equals() methods for each element each time you add an new element to it.

Upvotes: 1

卢声远 Shengyuan Lu
卢声远 Shengyuan Lu

Reputation: 32004

LinkedHashSet which keeps insertion-order can be used in your case.

HashSet: no order.

TreeSet: sorted set, but not keep insertion order.

EDIT: As Software Monkey commented, hashCode() and equals() should be overwritten in ContactObject to fit the hash-based Set.

Upvotes: 8

vsm
vsm

Reputation: 3383

For sure you can use TreeSet to store only once but a common mistake is do not override hashCode() and equal() methods:

This can fit for you:

 public boolean equals(Object obj) {
     if (!(obj instanceof ContactObject))
        return false;

     return this.id == ((ContactObject) obj).getId(); // you need to refine this
 }

 public int hashCode() {
     return name.hashCode();
 }

Upvotes: 3

sbridges
sbridges

Reputation: 25150

List<ContactObject> listContacts = new ArrayList<ContactObject>();
//populate...

//LinkedHashSet preserves the order of the original list
Set<ContactObject> unique = new LinkedHasgSet<ContactObject>(listContacts);
listContacts = new ArrayList<ContactOjbect>(unique);

Upvotes: 2

Related Questions