Die Beseitigung oder die Vermeidung hinzufügen von Duplikaten in einer ArrayList mit benutzerdefinierten Objekt
Habe ich ein benutzerdefiniertes Objekt in dieser Struktur
static class Node {
int col;
int row;
int g;
int h;
int f;
public Node(int col, int row, int g, int h) {
this.col = col;
this.row = row;
this.g = g;
this.h = h;
this.f = g+h;
}
}
Den col
und row
Variablen sind einzigartig und dürfen nur einmal vorkommen in ArrayList<Node> myList
.
Gibt es eine Möglichkeit, die optimale Weg, um zu vermeiden, hinzufügen oder überprüfung auf mögliche doppelte, ohne einen fiesen for-Schleife?
Ich bin mir bewusst, dass Set
Schnittstelle möglicherweise könnte eine Lösung für diese als Duplikate können nicht auftreten, aber ich habe eine Menge code jetzt, das will ich nicht umgestalten, wenn es nötig wird.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier sind Ihre Optionen. All diese Lösungen erfordern eine ordnungsgemäße Durchführung der
equals
undhashCode
. Da möchte manrow
undcol
einzigartig zu sein:Iteration über die
List
Sie nicht zu tun haben, die iteration selbst, aber genau das ist es, was den Aufruf
List.contains
tun. Diese ist ziemlich einfach:Diese iteriert, so dass Sie nicht haben, um schreiben Sie die Schleife.
List
zuSet
zuList
Hier haben Sie zwei sub-Optionen. Wenn Sie möchten, bewahren Sie die Reihenfolge der input-Liste, dann können Sie
LinkedHashSet
. Wenn Sie don ' T care, können Sie einfachHashSet
. Was ich meine ist, wenn ich eineList
mit Elementen A, B, C, konvertieren es in einHashSet
- und Rückseite produzieren kann eine andere Liste, wie B, C, A.LinkedHashSet
hält die Elemente in der insertion order, diesem problem entgegenzutreten. In jedem Fall werden Sie genau dies tun:Denken Sie daran, dass dies im wesentlichen zu tun iteration als gut, aber es ist eine hash-code-Verknüpfung anstelle der überprüfung jedes element der Gleichheit, es kann auch ein big deal mit genug Knoten. Wenn Ihre Liste von Knoten klein ist (weniger als 1000 Elemente), dann bezweifle ich dies machen viel Unterschied, und Sie können auch mit der ersten.
Konvertieren alles um
Set
Du hast erwähnt, dass dies würde erfordern, eine Menge refactoring im code, aber dies ist nicht eine schlechte Sache, vor allem, wenn Sie planen, die Arbeit an diesem code eine Menge in der Zukunft. Meine Faustregel ist, wenn das refactoring wird der code leichter zu pflegen, hinzufügen von ein wenig zusätzliche Entwicklungszeit nie eine schlechte Sache. Schreiben wartbaren, lesbaren und verständlichen code was die Experten tun (die Frage ist hier nicht relevant, aber diese Antwort ist). Da
Set
impliziert einzigartige Elemente undList
nicht, dann macht es Sinn, die änderung. Der compiler ziemlich viel zu Ihnen sagen, alle Orte, die Sie haben zu ändern, mit seinen Fehlern, und es wird wahrscheinlich weniger Zeit als Sie denken.Set
ab und setzen dieequals()
Methode?hashCode()
, aber ja.O(N)
.contains
und sehen, ob es wirklich so langsam. Wenn es beginnt, zu langsam ist, dann konvertieren Sie alles zuSet
.Fügen Sie eine equals-Methode in Knoten, falls möglich :
Und verwenden Sie dann
list-to-set-to-list
trick.Versuchen Sie diese Methode:
Update :
Wenn Sie wan ' T zu halten-Eingang um, verwenden Sie
LinkedHashSet
Fügen Sie alle Elemente zu einer neuen
Set
, dann setzen Sie alle Elemente von derSet
zu einem neuenList
. Das wird es machen.Finde ich immer seltsam zu sehen, Fälle, in denen Menschen verwenden möchten
List
(für dieget(int)
- Methode, Schätze ich), wenn Sie verlangen, unicity, das nur erreicht durchSet
.Sowieso, durch die Manipulation ein wenig die equals/hashcode (macht gleich zurück
true
wennrow
undcol
sind die gleichen) - Methode hinzufügen und Anrufe zuList#contains(Objekt)
, Sie hätte Ihr Ziel erreicht, ohne sacrifying IhreList
BEARBEITEN
Bemerkt, man könnte auch einen Komparator und sich auf
Collections#sort(List, Comparator)
, um Ihre Liste sortiert und Elemente mit dem gleichen Wert schmolz in nur einen Wert.Halten Sie sowohl eine Set-und eine Liste. Verwenden Sie das Set auf Duplikate überprüft werden sollen. Hinzufügen, Festlegen und Liste wenn kein dupe.
...unter der Annahme, dass Knoten hat einen .equals-Methode definiert...
Idealerweise würden Sie verwenden
Set
, aber wenn Sie möchten, um zu vermeiden, reimplementing Ihre Daten-Strukturen ausArrayList<Node>
zuSet
können Sie implementierenSet
als gatekeeper:Und so ist es ein "gatekeeper".
Alle Set-Operationen sind
O(1)
da Sie gehasht werden; minimale refactoring und keine bösen Schlaufen wie gewünscht.row
undcol
und nicht das ganze element?Node
's.equals()
: wo Sie überprüfen, ob die Zeilen und Spalten gleich sind, dann die Knoten selbst sind gleich.ArrayList
in gleicher Weise durch überschreiben der equals-Methode?