2011-07-18 8 views
8

Jest to dość częste pytanie, ale nie mogłem znaleźć tej części:Jak znaleźć duplikaty w ArrayList <Object>?

że mam do tej listy tablicy:

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

MyDataClass{ 
    String name; 
    String age; 
} 

Teraz muszę znaleźć duplikaty na podstawie age w MyDataClass i Usuń ich. Jak to jest możliwe za pomocą czegoś takiego jak HashSet, jak opisano here?

Zgaduję, że będziemy musieli nadpisać equals w MyDataClass?

  1. Ale co, jeśli nie mam tego luksusu?
  2. A jak HashSet rzeczywiście wewnętrznie znajduje i nie dodaje duplikatów? Widziałem jego implementację, ale nie mogłem tego zrozumieć.

Odpowiedz

14

sugeruję, że zastępują zarównoequals i hashCode (HashSet opiera się na obu!)

Aby usunąć duplikaty można po prostu stworzyć nową HashSet z ArrayList jako argumentu, a następnie jasne ArrayList i przywrócić elementy przechowywane w 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); 
    } 
} 

a następnie wykonaj

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

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

Ale co zrobić, jeśli nie mam luksus robi?

Potem proponuję zrobić jakiś dekorator klasy że robi świadczenia tych metod.

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); 
    } 
} 
+2

Zastanawiam się, czy PO chciała równości bazowej * tylko * na wieku zamiast zarówno nazwa, jak i wiek ... tak właśnie to pytanie czyta. Poza tym +1. – Jonik

+0

Prawda. Zostawię to jako ćwiczenie ;-) – aioobe

1

A jeśli nie są w stanie zastąpić „MyDataClass” 's hashCode i równa się metody można napisać klasy otoki, który obsługuje to.

1

proszę zobaczyć ten article który wyjaśnia znaczenie equals() i hashCode do HashSets

Również zobaczyć to wcześniej odpowiedział question

0
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; 
     } 
Powiązane problemy