Найти объекты в списке, где некоторые атрибуты имеют равные значения - PullRequest
4 голосов
/ 06 января 2010

Учитывая список объектов (все одного типа), как я могу убедиться, что он содержит только один элемент для каждого значения определенного атрибута, даже если equals () может возвращать false для таких элементов из-за большего количества атрибутов проверяется? В коде:

private void example() {
    List<SomeType> listWithDuplicates = new ArrayList<SomeType>();

    /*
     * create the "duplicate" objects. Note that both attributes passed to 
     * the constructor are used in equals(), though for the purpose of this 
     * question they are considered equal if the first argument was equal
     */
    SomeType someObject1 = new SomeObject1("hello", "1");
    SomeType someObject2 = new SomeObject1("hello", "2");

    List<SomeType> listWithoutDuplicates = removeDuplicates(listWithDuplicates)
    //listWithoutDuplicates should not contain someObject2
}

private List<SomeType> removeDuplicates(List<SomeType> listWithDuplicates) {
    /*
     * remove all but the first entry in the list where the first constructor-
     * arg was the same
     */
}

Ответы [ 4 ]

8 голосов
/ 06 января 2010

Может использовать набор в качестве промежуточного заполнителя для поиска дубликатов, как предложил Божо Вот пример реализации removeDuplicates().

private List<SomeType> removeDuplicates(List<SomeType> listWithDuplicates) {
    /* Set of all attributes seen so far */
    Set<AttributeType> attributes = new HashSet<AttributeType>();
    /* All confirmed duplicates go in here */
    List duplicates = new ArrayList<SomeType>();

    for(SomeType x : listWithDuplicates) {
        if(attributes.contains(x.firstAttribute())) {
            duplicates.add(x);
        }
        attributes.add(x.firstAttribute());
    }
    /* Clean list without any dups */
    return listWithDuplicates.removeAll(duplicates);
}
1 голос
/ 06 января 2010

Может быть, HashMap можно использовать так:

  private List<SomeType> removeDuplicates(List<SomeType> listWithDuplicates) {
   /*
   * remove all but the first entry in the list where the first constructor-
   * arg was the same
   */
   Iterator<SomeType> iter = listWithDuplicates.iterator();
   Map<String, SomeType> map = new HashMap<String, SomeType>();
   while(iter.hasnext()){
         SomeType i = iter.next();
         if(!map.containsKey(i.getAttribute())){
             map.put(i.getAttribute(), i);
         }
   }
   //At this point the map.values() is a collection of objects that are not duplicates.



  }
0 голосов
/ 06 января 2010

Я бы посмотрел на реализацию интерфейса Comparator для чего-то подобного. Если есть один или два простых атрибута, которые вы хотите использовать для сравнения, это довольно просто.

Смежный вопрос: Как лучше всего сравнить две коллекции на Java и действовать по ним?

0 голосов
/ 06 января 2010

Если бы подходило equals(), я мог бы порекомендовать некоторые "стандартные" классы / методы коллекций. На самом деле, я думаю, что ваш единственный вариант будет либо

  • копировать каждый элемент в другой список после первой проверки всех предшествующих элементов в исходном списке на наличие дубликатов; или

  • удалить из вашего списка любой элемент, для которого вы нашли дубликат в предыдущем месте. Для удаления из списка лучше всего использовать LinkedList, где удаление не так дорого.

В любом случае проверка на наличие дубликатов будет операцией O (n ^ 2), увы.


Если вы собираетесь выполнять много подобных операций, возможно, стоит заключить элементы списка в другой класс, который возвращает хеш-код на основе ваших собственных определенных критериев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...