2016-12-02 5 views
0

EDITED/ noch GELÖST für bessere Antwort suchen Ich habe eine Antwort hier How do I remove repeated elements from ArrayList? und es ist meine Frage arbeitet, ist Bezug auf ONLY Liste und nicht festgelegt werden. Da eine durchgehende Anwendungsflussliste implementiert wurde und es schwierig für mich ist, alle Listenreferenzen auf "Referenz setzen" zu setzen, wie https://docs.oracle.com/javase/7/docs/api/java/util/List.html hat, bekommt (..) Set nicht get (..).equals und hasCode arbeiten nicht wie erwartet

Jedes Objekt, das hinzugefügt wird, ist eine neue Instanz. hallo Ich habe eine Modellklasse

public final class MyClass implements Comparable<MyClass> { 

    public static final int APP = 0; 
    public static final int FILE = 1; 
    public static final int FOLDER = 2; 

    private String name; 
    private String path; 
    private String pkg; 
    private Long size; 
    private boolean selected; 
    private Integer type; 


    public MyClass(String name, String path, String pkg, Long size, boolean selected, int type) { 
     this.name = name; 
     this.path = path; 
     this.pkg = pkg; 
     this.size = size; 
     this.selected = selected; 
     this.type = type; 


     if (!TextUtils.isEmpty(path)) { 
      File file = new File(path); 
      if (file.exists()) { 
       this.size = file.length(); 
      } 
     } 
    } 

    public String getName() { 
     return name; 
    } 

    public String getPath() { 
     return path; 
    } 

    public String getSize() { 
     return FileUtils.getReadableFileSize(size); 
    } 

    public boolean isSelected() { 
     return selected; 
    } 

    public void setSelected(boolean selected) { 
     this.selected = selected; 
    } 


    public Integer getType() { 
     return type; 
    } 

    public String getPkg() { 
     return pkg; 
    } 

    @Override 
    public String toString() { 
     return "{Pkg=" + pkg + ", Path=" + path + ", size=" + size + ", hashcode: " + hashCode() +"}"; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) 
      return true; 

     if (o == null || getClass() != o.getClass()) 
      return false; 

     MyClass myclass = (MyClass) o; 

     if (path != null ? !path.equals(myclass.path) : myclass.path != null) 
      return false; 

     if (pkg != null ? !pkg.equals(myclass.pkg) : myclass.pkg != null) 
      return false; 

     return size != null ? size.equals(myclass.size) : myclass.size == null; 

    } 

    @Override 
    public int hashCode() { 
     int result = path != null ? path.hashCode() : 0; 
     result = 31 * result + (pkg != null ? pkg.hashCode() : 0); 
     result = 31 * result + (size != null ? size.hashCode() : 0); 
     return result; 
    } 

    @Override 
    public int compareTo(MyClass myclass) { 
     return myclass.getType().compareTo(this.type); 
    } 
} 

Aber wenn ich gemeinsames Objekt erstellen, wird diese Aufgabe zur Liste hinzugefügt zu werden, auch wenn ihr Hash-Code gleich ist es duplizieren in der Liste ist. Alles, was ich hier falsch mache.

Ausgabe von toString der Liste ist wie folgt:

[{ 
    Pkg = com.a.bc, 
    Path = /data/app/com.a.bc - 1/base.apk, 
    size = 1800820, 
    hashcode: -908060882 
}, { 
    Pkg = com.a.b.c, 
    Path = /data/app/com.a.b.c - 1/base.apk, 
    size = 21279534, 
    hashcode: 1116685502 
}, { 
    Pkg = com.a.b.c, 
    Path = /data/app/com.a.b.c - 1/base.apk, 
    size = 21279534, 
    hashcode: 1116685502 
}] 

ist hier etwas schmutzig Implementierung, aber das ist nicht das, was ich suchte ...

private final class DuplicateFilterArrayList<E> extends ArrayList<E> { 

     private DuplicateFilterArrayList() { 

     } 

     @Override 
     public boolean add(E object) { 
      if (object instanceof MyClass) { 
       if (!contains(object)) { 
        return super.add(object); 
       } else { 
        Logger.error(TAG, "Object already exists go home"); 
        return false; 
       } 
      } else { 
       throw new IllegalArgumentException("Unsupported Object type " + object.getClass().getSimpleName()); 
      } 
     } 

     @Override 
     public boolean contains(Object object) { 
      if (object instanceof MyClass) { 
       MyClass otherMyClassObjec = (MyClass) object; 
       for (E myClassItem : this) { 
        MyClass newMyClass = (MyClass) myClassItem; 
        if (newMyClass.equals(otherMyClassObjec) && newMyClass.hashCode() == otherMyClassObjec.hashCode()) { 
         return true; 
        } 
       } 
      } 

      return false; 
     } 

    } 
+2

Warum sollten Sie erwarten, dass eine "Liste" keine Duplikate enthält? Eine 'List' prüft nicht auf Duplikate, nur ein' Set' würde das tun. Sie haben den Code zum Erstellen und Hinzufügen von Einträgen zur "Liste" nicht angezeigt. –

+0

@CoffeeMonkey ist jedes Mal eine komplett neue Instanz, aber seine Eigenschaften sind mehr oder ähnlich. – sector11

+0

Sorry, das macht keinen Sinn. Eine 'List' verhindert keine Duplikate. Sie müssen ein Set verwenden, wenn Sie verhindern möchten, dass Duplikate gespeichert werden. –

Antwort

1

Bevor die Liste hinzuzufügen, Überprüfen Sie, ob sich die Instanz bereits in der Sammlung befindet, indem Sie die Methode contains für die Sammlung verwenden (in diesem Fall Liste). Dann können Sie wählen, dass Sie nicht erneut hinzufügen, wenn es bereits enthalten ist. Es sollte funktionieren, wenn Sie die Methoden equals und hashCode korrekt implementiert haben.

+0

seine völlig neue Instanz jedes Mal, aber seine Eigenschaften sind mehr oder ähnlich. – sector11

+1

@ sector11 * Es sollte funktionieren, wenn Sie die equals und hashCode Methoden korrekt implementiert haben. * –

+0

@ScaryWombat Code ist hier, es funktioniert nicht wie erwartet: '(Bitte sehen, ob ich etwas falsch machen kann – sector11

0

Erstellen Sie Ihre eigene Klasse (MYArrayList), die ArrayList erweitert. Machen Sie den Rückgabetyp als Liste selbst. Rest alles wird gleich sein.

Liste list = new MyArrayList

MyArrayList erweitert Arraylist <>

Überschreibung Methode MyArrayList hinzufügen, so dass vor myClass in Liste seiner prüfen hinzufügen, wenn diese Liste bereits enthält oder nicht.

Aber denken Sie daran, dies wird die Leistung beeinträchtigen, da es über alle Elemente in der Liste iterieren wird, nur um die Duplizität beim Einfügen zu überprüfen.

+0

Ja, dies ist eine der Möglichkeiten und es funktioniert gut, aber viele Änderungen an der Objekt-Liste. Liste myList = new MyCustomList (); – sector11

+0

Ja, das wird erforderlich sein. In wie vielen Orten haben Sie solche Initialisierung. Besser, eine API zu geben und sie an nur einer Stelle zu haben, was dir in Zukunft auch helfen wird – Roshan

+0

zu beantworten, was ich als Teillösung umgesetzt habe aber nicht die letzte. – sector11

Verwandte Themen