Удалить дубликаты объектов из ArrayList в Android

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

Что я имею

Я обращаюсь к Журналу вызовов с 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(); } 

// Getters and Setters и COnstructor ….

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

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

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

HashSet: нет порядка.

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

EDIT: Как комментирует Software Monkey, hashCode() и equals() должны быть перезаписаны в ContactObject чтобы соответствовать ContactObject на основе хэша.

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

Конечно, вы можете использовать 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(); } 

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

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

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

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

Пример удаления дубликата с использованием компаратора

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

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

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

 public ArrayList<Contact> removeDuplicates(ArrayList<Contact> list){ Set set = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { if(((Contact)o1).getNumber().equalsIgnoreCase(((Contact)o2).getNumber())){ return 0; } return 1; } }); set.addAll(list); final ArrayList newList = new ArrayList(set); return newList; } 

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

PS: Кредит отправляется в Ниланчала по этой статье

Intereting Posts
Тестирование Android Realm с RxJava – «открыто из потока без Looper» Исключение Исключить исключение указателя в всплывающем окне подсказок на Samsung Galaxy Android 7 Как показать текст в настраиваемом маркере Как узнать номер SimSlot для каждого Call / sms? Вырезание Action Bar с помощью SlidingMenu и Overlay of ActionBar Sherlock Отображение части веб-страницы на веб-обозревателе Android Android-приложение. Как обнаружить в коде, если приложение обновляется или обновляется? Любые хорошие инструменты ORM для разработки Android? Добавить зависимость от плагина Android Cordova UnsupportedOperationException: isDirectory не реализован: isDirectory не реализован Могу ли я переопределить кнопку «Главная» в моем приложении? Отображать дату / время UTC в дату / время в соответствии с текущим часовым поясом Xamarin .jar binding – «Bitmap не найден» Обрезать изображение без OutOfMemory – Android Комплексный метод andDraw () для андроидов и пользовательский макет