Захват дубликатов из ArrayList

У меня возникают проблемы с удалением повторяющихся объектов из ArrayList. Я разбираю XML в том, что я называю объектом IssueFeed. Это состоит из симптома, проблемы, решения.

Большинство моих объектов уникальны и не имеют симптомов, проблем, решений, но некоторые из них имеют один и тот же симптом, но имеют другую проблему.

Я пытаюсь выполнить несколько вещей.

  1. Захват объектов, которые имеют один и тот же симптом как дубликат Arraylist
  2. Удалите дублирующиеся элементы из основного списка, оставив по крайней мере 1 элемент с этим симптомом, который будет отображаться.
  3. Когда пользователь нажимает на элемент, который, как нам известно, имеет дубликаты, задайте дубликаты данных Arraylist в моем списке / адаптере.

Шаги, которые я сделал.

  1. Я попытался сортировать объекты, и я могу захватить дубликаты, однако не уверен, как удалить все, кроме одного из основного списка.
  2. 2 Петли между списком и поиск объектов, которые сами по себе и не симптом = симптом, а затем удалить и обновить мой дублированный массив и основной массив.

Некоторый код

IssueFeed – объект

public IssueFeed(String symptom, String problem, String solution) { this.symptom = symptom; this.problem = problem; this.solution = solution; } public String getSymptom() { return symptom; } public String getProblem() { return problem; } public String getSolution() { return solution; } 

Мой ArrayList<IssueFeed>

 duplicateDatalist = new ArrayList<IssueFeed>(); // list of objects thats share a symptom list_of_non_dupes = new ArrayList<IssueFeed>(); // list of only objects with unique symptom mIssueList = mIssueParser.parseLocally(params[0]); // returns ArrayList<IssueFeed> of all objects 

Я могу получить дубликаты следующим кодом sort ниже.

 Collections.sort(mIssueList, new Comparator<IssueFeed>(){ public int compare(IssueFeed s1, IssueFeed s2) { if (s1.getSymptom().matches(s2.getSymptom())) { if (!duplicateDatalist.contains(s1)) { duplicateDatalist.add(s1); System.out.print("Dupe s1 added" + " " + s1.getSymptom() + ", " + s1.getProblem() + "\n"); } if (!duplicateDatalist.contains(s2)) { duplicateDatalist.add(s2); System.out.print("Dupe s2 added" + " " + s2.getSymptom() + ", " + s2.getProblem() + "\n"); } } return s1.getSymptom().compareToIgnoreCase(s2.getSymptom()); } }); 

Теперь мне нужно создать новый список без дуплексов. Этот код добавляет только все объекты. : /

 for (int j = 0; j < mIssueList.size(); j++) { IssueFeed obj = mIssueList.get(j); for (int i = 0; i < mIssueList.size(); i++) { IssueFeed obj_two = mIssueList.get(j); if (obj.getSymptom().matches(obj_two.getSymptom())) { if (!list_non_dupes.contains(obj_two)) { list_non_dupes.add(obj_two); } break; } else { if (!list_non_dupes.contains(obj_two)) { list_non_dupes.add(obj_two); } } } } 

Если вы можете изменить объект IssueFeed рассмотрите возможность переопределения методов equals() и hashCode() и используйте набор для поиска дубликатов. Например

 import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; class IssueFeed { private String symptom; private String problem; private String solution; public IssueFeed(String symptom, String problem, String solution) { this.symptom = symptom; this.problem = problem; this.solution = solution; } public String getSymptom() { return symptom; } public String getProblem() { return problem; } public String getSolution() { return solution; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((symptom == null) ? 0 : symptom.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; IssueFeed other = (IssueFeed) obj; if (symptom == null) { if (other.symptom != null) return false; } else if (!symptom.equals(other.symptom)) return false; return true; } @Override public String toString() { return "IssueFeed [symptom=" + symptom + ", problem=" + problem + ", solution=" + solution + "]"; } } public class Sample { public static void main(String[] args) { List<IssueFeed> mainList = new ArrayList<IssueFeed>( Arrays.asList(new IssueFeed[] { new IssueFeed("sym1", "p1", "s1"), new IssueFeed("sym2", "p2", "s2"), new IssueFeed("sym3", "p3", "s3"), new IssueFeed("sym1", "p1", "s1") })); System.out.println("Initial List : " + mainList); Set<IssueFeed> list_of_non_dupes = new LinkedHashSet<IssueFeed>(); List<IssueFeed> duplicateDatalist = new ArrayList<IssueFeed>(); for(IssueFeed feed : mainList){ if(!list_of_non_dupes.add(feed)) { duplicateDatalist.add(feed); } } mainList = new ArrayList<IssueFeed>(list_of_non_dupes); // Remove the duplicate items from the main list, leaving at least 1 item with that symptom to be display list_of_non_dupes.removeAll(duplicateDatalist); // list of only objects with unique symptom System.out.println("Fina main list : " + mainList); System.out.println("Unique symptom" + list_of_non_dupes); System.out.println("Duplicate symptom" + duplicateDatalist); } } 

Вы должны повторять бит ArrayList дважды. Используя этот подход, вам даже не нужно сортировать ArrayList по дубликатам (Collections.sort – это операция O (n log n)) и может обрабатывать список в линейном времени. Вам также не нужно переопределять equals() и hashCode() для объектов IssueFeed.

На первой итерации вы должны заполнить HashMap симптомов, хэшированных против количества вхождений в ArrayList. Вероятно, это

 class SymptomInfo { int incidence; boolean used; } HashMap<String, SymptomInfo> symptomIncidence = new HashMap<String, SymptomInfo>(); 

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

Во второй итерации через ArrayList вы должны посмотреть значение incidence из хэш-карты и найти общее количество случаев этого симптома. Это быстрый и простой способ выяснить, следует ли добавлять объект в duplicateDataList или list_of_non_dupes . Кроме того, в первый раз, когда вы сталкиваетесь с объектом с определенным значением symptom , вы можете установить значение true. Итак, если вы сталкиваетесь с объектом, где used true, вы знаете, что это дублирующее событие и может удалить его из основного списка.