2011-07-18 20 views
8

Ésta es una pregunta bastante común, pero no pude encontrar esta parte:¿Cómo encontrar duplicados en una ArrayList <Object>?

Decir que tengo esta lista de arreglo:

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

MyDataClass{ 
    String name; 
    String age; 
} 

Ahora, necesito encontrar duplicados en la base de age en MyDataClass y eliminarlos. ¿Cómo es posible usar algo como HashSet como se describe en here?

Supongo que tendremos que sobrescribir equals en MyDataClass?

  1. Pero, ¿y si no tengo el lujo de hacer eso?
  2. ¿Y cómo HashSet realmente encuentra internamente y no agrega duplicados? Vi que es la implementación here in OpenJDK pero no pude entender.

Respuesta

14

me gustaría sugerir que se reemplaza tantoequals y hashCode (HashSet se basa en los dos!)

Para eliminar los duplicados simplemente podría crear un nuevo HashSet con el ArrayList como argumento, y luego despejado ArrayList y volver a colocar los elementos almacenados en 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); 
    } 
} 

y luego hacer

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

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

Pero, ¿y si no tengo el lujo de hacer eso?

Entonces yo sugiero que hacer algún tipo de clase decoradora que hace proporcionar estos métodos.

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

Me pregunto si OP quería la igualdad de base * * sólo en la edad en lugar de tanto nombre como edad ... así es como se lee la pregunta de todos modos. Aparte de eso, +1. – Jonik

+0

Es cierto. Lo dejo como un ejercicio ;-) – aioobe

1

Y si usted no es capaz de anular "MyDataClass" 's hashCode y equals métodos podría escribir una clase contenedora que se encarga de esto.

1

consulte este article que explica la importancia de equals() y hashCode a HashSets

También, ver este respondidas anteriormente 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; 
     } 
Cuestiones relacionadas