Удалить дубликаты объектов из ArrayList в Android - PullRequest
7 голосов
/ 16 июля 2011

Я знаю, что это обсуждалось здесь снова и снова, но ни один из примеров, которые я пробовал, не работал для меня.

То, что у меня есть

Я получаю доступ к журналу звонков с Android и получаю список всех сделанных звонков.Конечно, здесь я получаю много дубликатов.Сначала я создаю список

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

Затем я добавляю в него объекты

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);

Класс Contact Object прост:

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
}

Что мне нужно

Мне нужно иметь контакт только один раз в списке.Как я читал здесь, есть несколько вещей, которые можно сделать, например, Set, HashSet, TreeSet.TreeSet кажется лучшим, поскольку он поддерживает порядок так же, как я получаю его из журнала вызовов.Я пытался заставить мой код работать с ним, но безуспешно.Кто-нибудь может быть так любезен, чтобы дать мне пример кода на основе моего примера.Спасибо за ваше время.

Рабочее решение. Спасибо всем за поддержку, вы сделали мой день.

В ContactObject переопределите два метода

 @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();
     }

// Геттеры и сеттеры и конструктор ....

Просто используйте его как

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

Ответы [ 5 ]

8 голосов
/ 16 июля 2011

LinkedHashSet , который сохраняет порядок вставки, может использоваться в вашем случае.

HashSet: нет заказа.

TreeSet: отсортированный набор, но не сохраняет порядок вставки.

РЕДАКТИРОВАТЬ: Как прокомментировал Software Monkey, hashCode() и equals() должны быть перезаписаны в ContactObject, чтобы соответствовать набору на основе хеша.

5 голосов
/ 25 октября 2016

Удалить дублирование пользовательского объекта

Пример удаления дубликата с помощью Comparator

Предположим, у вас есть класс "Контакт"

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;
}

Вот как вы можете удалить повторяющиеся записи, используя Установить , просто передайте свой список в функцию, и она будет работать для вас.Будет возвращен новый список, в котором не будет дублированных контактов.

 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;
}

Это сработало для меня, поэтому, пожалуйста, попробуйте и дайте мне свой отзыв.Спасибо

PS: Кредит идет на Nilanchala в этой статье

2 голосов
/ 16 июля 2011

Конечно, вы можете использовать TreeSet для хранения только один раз, но распространенная ошибка - не переопределять методы hashCode () и equal ():

Это может подойти вам:

 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();
 }
2 голосов
/ 16 июля 2011
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);
1 голос
/ 18 июля 2011

Вместо этого используйте Set.

Набор работает как математическая коллекция, поэтому он не допускает дублирование элементов.

Поэтому он проверяет методы равенства и .equals () для каждого элементакаждый раз, когда вы добавляете в него новый элемент.

...