Как найти дубликаты в ArrayList <Object>? - PullRequest
10 голосов
/ 18 июля 2011

Это довольно распространенный вопрос, но я не смог найти эту часть:

Скажите, у меня есть список массивов:

List<MyDataClass> arrayList = new List<MyDataClass>;

MyDataClass{
   String name;
   String age;
}

Теперь мне нужно найти дубликаты на основе age в MyDataClass и удалить их. Как это возможно, используя что-то вроде HashSet, как описано здесь ?

Полагаю, нам нужно будет перезаписать equals в MyDataClass?

  1. Но что, если я не могу позволить себе такую ​​роскошь?
  2. А как HashSet на самом деле внутренне находит и не добавляет дубликаты? Я видел его реализацию здесь, в OpenJDK , но не смог понять.

Ответы [ 4 ]

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

Я бы посоветовал вам переопределить оба equals и hashCode (HashSet зависит от обоих!)

Чтобы удалить дубликаты, вы можете просто создать новый HashSet с ArrayList в качестве аргумента, а затем очистить ArrayList и вернуть элементы, хранящиеся в HashSet.

class MyDataClass {
    String name;
    String age;

    @Override
    public int hashCode() {
        return name.hashCode() ^ age.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof MyDataClass))
            return false;

        MyDataClass mdc = (MyDataClass) obj;
        return mdc.name.equals(name) && mdc.age.equals(age);
    }
}

А потом

List<MyDataClass> arrayList = new ArrayList<MyDataClass>();

Set<MyDataClass> uniqueElements = new HashSet<MyDataClass>(arrayList);
arrayList.clear();
arrayList.addAll(uniqueElements);

Но что, если я не могу позволить себе такую ​​роскошь?

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

class MyDataClassDecorator {

    MyDataClass mdc;

    public MyDataClassDecorator(MyDataClass mdc) {
        this.mdc = mdc;
    }

    @Override
    public int hashCode() {
        return mdc.name.hashCode() ^ mdc.age.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof MyDataClassDecorator))
            return false;

        MyDataClassDecorator mdcd = (MyDataClassDecorator) obj;
        return mdcd.mdc.name.equals(mdc.name) && mdcd.mdc.age.equals(mdc.age);
    }
}
1 голос
/ 18 июля 2011

см. Эту статью , в которой объясняется важность equals() и hashCode для HashSets

Кроме того, см. Этот ранее отвеченный вопрос

1 голос
/ 18 июля 2011

И если вы не можете переопределить hashCode "MyDataClass" и методы equals, вы можете написать класс-оболочку, который обрабатывает это.

0 голосов
/ 29 августа 2013
public Set<Object> findDuplicates(List<Object> list) {
        Set<Object> items = new HashSet<Object>();
        Set<Object> duplicates = new HashSet<Object>();
        for (Object item : list) {
            if (items.contains(item)) {
                duplicates.add(item);
                } else { 
                    items.add(item);
                    } 
            } 
        return duplicates;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...