Поиск дубликатов в коллекции
Как лучше всего найти и отметить повторяющиеся объекты в коллекции? Допустим, у нас есть список лиц, и наша дублирующая стратегия основана на точном совпадении имени и фамилии.
- идентифицировать все дубликаты
- отметьте каждого дубликата человека, указывая, что это дубликат
- для каждого дубликата человека определите объект, который является дубликатом
Есть ли простой способ сделать это с гуавой?
4 ответов:
Для этого Вам не нужна гуава:
Тем не менее, вы можете использовать гуавуList<Person> people = ... Map<Name, Person> peopleByName = new HashMap<>(); for (Person person : people) { // Name is a simple value class with equality based on its fields Name name = new Name(person.getFirstName(), person.getLastName()); Person firstPersonWithName = peopleByName.get(name); if (firstPersonWithName == null) { peopleByName.put(name, person); } else { // or whatever you do to mark a duplicate person.setDuplicateOf(firstPersonWithName); } }TableвместоMapи избежать необходимости создаватьName... например, используйте имя в качестве ключей строк, а фамилию-в качестве ключей столбцов. Другой вариант-использоватьMultimaps.indexдля индексации всех людей в вашем списке по именам. Тогда для каждого списка людей, сопоставленного с определенным именем, первым человеком будет первый человек с этим именем из вашего списка, а остальные будут дубликатами.
Вы можете попробовать использовать TreeMultimap гуавы.
Создайте новый TreeMultimap, инициализируя его с помощью компаратора для сравнения ваших людей, как вам нравится: TreeMultimap.создать (компаратор, упорядочивание.произвольно())
Вот модульный тест:
package org.test.guava; import java.util.Arrays; import java.util.Comparator; import java.util.List; import org.junit.Test; import com.google.common.collect.Multimap; import com.google.common.collect.Ordering; import com.google.common.collect.TreeMultimap; public class GuavaTest { private static class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "Person [name=" + name + "]"; } } @Test public void test() throws Exception { List<Person> persons = Arrays.asList(new Person("person1"), new Person("person2"), new Person("person1")); Comparator<Person> comparator = new Comparator<Person>() { public int compare(Person o1, Person o2) { return o1.getName().compareTo(o2.getName()); } }; Multimap<Person, Person> groups = TreeMultimap.create(comparator, Ordering.arbitrary()); for(Person person : persons) { groups.put(person, person); } System.out.println(groups.asMap()); } }
Почему бы не попробовать переопределить .equals () в объекте person. Затем добавьте новое поле для каждого объекта person 'duplicateOf' или что-то еще.
Затем просто пройдите по массиву, сверяя каждого человека с другими. Если поле persons 'duplicateOf' равно null, пропустите его. Если.equals() возвращает true вы можете установить поле 'duplicateOf'.
Человек класса должен реализовать
boolean equals(Object o).Тогда вы можете найти дубликаты следующим образом:
У вас где-то есть:
Collection<Person> list;Person[] persons = list.toArray(); Integer[] duplicateOf = new Integer[persons.length]; Arrays.fill(duplicateOf, -1); // For all the values in the Collection for (int i = 0; i < persons.length; i++) { // Find the duplicate for (int j = 0; j < persons.length; j++) { if (persons[i].equals(persons[j]) && i != j) duplicateOf[j] = i; } }Теперь у вас есть массив
duplicateOf, который вы можете прочитать следующим образом: дубликат элементаjнаходится в индексеduplicateOf[j].
Comments