Cross vergleichen ArrayList-Elemente, und entfernen Sie Duplikate
Ich habe eine ArrayList<MyObject>
dass kann (muss aber nicht) enthalten Duplikate von MyObject
muss ich aus der Liste entfernen. Wie kann ich dies in einer Weise, dass ich nicht haben, um zu überprüfen, Vervielfältigung zweimal als würde ich tun, wenn ich waren zum Durchlaufen der Liste in zwei for-Schleifen und Kreuz überprüfen jedes Element mit jedem anderen Element.
Brauche ich nur um zu überprüfen, jedes Element einmal, so dass der Vergleich A:B
ist genug - ich will nicht zu vergleichen B:A
wieder, als ich bereits getan habe.
Außerdem; kann ich einfach entfernen Sie Duplikate aus der Liste , während looping? Oder wird das irgendwie teilen Sie die Liste und meine Schleife?
Edit: Okay, ich habe vergessen, ein wichtiger Teil der Suche über die ersten Antworten: Ein doppelte von MyObject
ist nicht nur gemeint, in die Java Art Sinn Objekt.equals(Object), aber ich muss in der Lage sein zu vergleichen, Objekte mit Hilfe meines eigenen Algorithmus, der die Gleichheit der MyObject
s wird berechnet mit einem Algorithmus, der überprüft das Objekt Felder in einer besonderen Weise, die ich implementieren muss!
Desweiteren kann ich nicht einfach überschreiben euqals
im MyObject
da gibt es mehrere, verschiedene Algorithmen, die die Implementierung der verschiedenen Strategien, die zur überprüfung der Gleichheit zweier MyObject
s - z.B. gibt es eine einfache HashComparer
und eine komplexere EuclidDistanceComparer
sowohl als AbstractComparers
Implementierung verschiedener algorithmen für die public abstract boolean isEqual(MyObject obj1, MyObject obj2);
- Ein TreeSet mit einem benutzerdefinierten Komparator sollte den trick tun.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sortieren Sie die Liste, und die Duplikate werden nebeneinander, so dass Sie leicht zu identifizieren und zu entfernen. Gehen Sie einfach durch die Liste erinnern, den Wert des vorherigen Elements, so können Sie vergleichen Sie es mit dem aktuellen. Wenn Sie identisch sind, entfernen Sie den aktuellen Eintrag.
Und wenn Sie verwenden Sie eine gewöhnliche
for
-Schleife durch die Liste gehen, kontrollieren Sie die aktuelle position. Das bedeutet, dass, wenn Sie ein Element entfernen, können Sie verringern Sie die position (n--
), so dass das nächste mal um die Schleife besuchen die gleiche position (die nun den nächsten Punkt).Müssen Sie einen benutzerdefinierten Vergleich in Ihrer Art? So schwer ist das nicht:
Ich geschrieben habe das Beispiel so, dass
getThing().compareTo()
steht für das, was Sie tun wollen, um vergleichen Sie die beiden Objekte. Sie müssen eine Ganzzahl zurück, die ist gleich null, wenn Sie identisch sind, größer als 1, wenn A1 größer ist als o2 und -1, wenn o1 kleiner als o2. WenngetThing()
zurückgegebenString
oder eineDate
würden Sie ganz eingestellt, da diese Klassen haben einecompareTo
Methode bereits. Aber Sie können beliebigen code, den Sie brauchen, um in Ihrem benutzerdefiniertenComparator
.x1 != x2
dann zurückx1 - x2
. Ansonsten zurücky1 - y2
.isEqual
und Sie nicht möchten, neu zu schreiben, können Sie schreiben einen benutzerdefinierten Vergleich, die zuerst überprüftisEqual
und gibt 0 zurück, wenn es wahr ist, aber sonst fällt zurück auf den Vergleich der beiden Objekte'System.identityHashCode
Werte (wie vorgeschlagen von @ante oben).Erstellen Sie einen Satz und es wird entfernen Sie die Dubletten automatisch für Sie, wenn die Reihenfolge ist nicht wichtig.
Instanziieren Sie ein neues set-basierte Sammlung HashSet. Vergessen Sie nicht, Implementierung von equals und hashcode, für MyObject.
Glück!
Wenn der Objekt-Reihenfolge ist unbedeutend
Wenn die Reihenfolge nicht wichtig ist, können Sie die Elemente der Liste in eine
Set
:Duplikate werden automatisch entfernt.
Wenn der Objekt-Reihenfolge ist wichtig
Wenn der Bestellung eine Bedeutung hat, dann können Sie manuell überprüfen Sie nach Duplikaten, z.B. mit diesem snippet:
Damit entfernen Sie alle Duplikate, verlassen die letzten doppelten Wert als original-Eintrag. Darüber hinaus wird es prüfe jede Kombination nur einmal.
, Die Mit Java 8
Java-Streams macht es noch eleganter:
Wenn Sie brauchen, um Bedenken Sie zwei Objekte gleich auf der Grundlage Ihrer eigenen definition, können Sie das folgende tun:
(von Stuart Marks)
Und dann könnte man dies tun:
Darüber hinaus
Können Sie nicht ändern eine Liste, während ein
Iterator
(die ist in der Regel in einer for-each-Schleife), wird die Schleife durch ein array. Dies wirft einConcurrentModificationException
. Sie können ändern Sie das array, wenn Sie Schleife es mit einer for-Schleife. Dann müssen Sie Steuern die iterator-position (Dekrementieren es beim entfernen eines Eintrags).Oder http://docs.oracle.com/javase/6/docs/api/java/util/SortedSet.html wenn Sie brauchen, sort-order..
BEARBEITEN: Was ist die Ableitung von http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html, es wird Ihnen erlauben, zu passieren, in einem Komparator in der Bauzeit. Überschreiben Sie
add()
verwenden Ihre Komparator anstelle vonequals()
- dies gibt Ihnen die Flexibilität, unterschiedliche Sätze, die bestellt werden nach Ihren Komparator und implementieren Sie Ihre "Gleichheit"-Strategie.Vergessen Sie nicht über
equals()
undhashCode()
obwohl...