Gibt es dafür Methoden? Ich suchte, konnte aber keine finden.
Eine andere Frage: Ich benötige diese Methoden, um Dateien filtern zu können. Einige sind AND
Filter und andere OR
Filter (wie in der Mengenlehre), daher muss ich nach allen Dateien und den ArrayLists, die diese Dateien enthalten, filtern.
Sollte ich eine andere Datenstruktur verwenden, um die Dateien zu speichern? Gibt es noch etwas, das eine bessere Laufzeit bietet?
java
list
union
intersection
Yotamoo
quelle
quelle
Vector
? Diese Klasse wurde seit Java 1.2 nicht mehr empfohlen.Vector
Thread-übergreifende Interaktionen, aber auch für diese Anwendungsfälle gibt es sicherere Datenstrukturen. Siehe auch diese Frage . Jede Bibliothek, dieVector
2016 noch benutzt wird, ist meiner Meinung nach sehr verdächtig.Antworten:
Hier ist eine einfache Implementierung ohne Verwendung einer Bibliothek eines Drittanbieters. Hauptvorteil gegenüber
retainAll
,removeAll
undaddAll
ist , dass diese Methoden nicht verändern den ursprünglichen Listen Eingang zu den Methoden.quelle
HashSet
für verwenden,intersection
damit die durchschnittliche Fallleistung O (n) anstelle von O (n ^ 2) ist.Sammlung (also auch ArrayList) haben:
Verwenden Sie eine Listenimplementierung, wenn Sie Wiederholungen akzeptieren, eine Set-Implementierung, wenn Sie dies nicht tun:
quelle
HashSet
stattdessen a zu verwenden.addAll()
Union für Listen ist; Es wird nur die zweite Liste mit dem Ende der ersten verknüpft. Eine Vereinigungsoperation würde das Hinzufügen eines Elements vermeiden, wenn die erste Liste es bereits enthält.Dieser Beitrag ist ziemlich alt, aber dennoch war er der erste, der bei der Suche nach diesem Thema bei Google auftauchte.
Ich möchte ein Update mit Java 8-Streams geben, die (im Grunde) dasselbe in einer einzigen Zeile tun:
Wenn jemand eine bessere / schnellere Lösung hat, lassen Sie es mich wissen, aber diese Lösung ist ein netter Einzeiler, der leicht in eine Methode aufgenommen werden kann, ohne eine unnötige Hilfsklasse / -methode hinzuzufügen, und dennoch die Lesbarkeit beibehält.
quelle
Set
und verwenden Sie dann diecontains
Methode des Sets . Nicht alles im Leben muss mit Streams gemacht werden.Gewerkschaft wird
removeAll
und dann seinaddAll
.Weitere Informationen finden Sie in der Dokumentation der Sammlung (ArrayList ist eine Sammlung) http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html
quelle
retainAll()
undremoveAll()
sind O (n ^ 2) Operationen auf Listen. Wir können es besser machen.retainAll
von {1, 2, 2, 3, 4, 5} über {1, 2, 3} ergibt {1, 2, 2, 3}. Sollte es nicht {1, 2, 3} sein, um die Kreuzung zu sein?Gewerkschaften und Schnittpunkte werden nur für Mengen definiert, nicht für Listen. Wie du erwähnt hast.
Überprüfen Sie die Guavenbibliothek auf Filter. Auch Guave bietet echte Schnittpunkte und Gewerkschaften
quelle
Sie können
CollectionUtils
von Apache Commons verwenden .quelle
Die markierte Lösung ist nicht effizient. Es hat eine O (n ^ 2) -Zeitkomplexität. Was wir tun können, ist, beide Listen zu sortieren und einen Schnittalgorithmus wie den folgenden auszuführen.
Dieser hat eine Komplexität von O (n log n + n), die in O (n log n) liegt. Die Vereinigung erfolgt auf ähnliche Weise. Stellen Sie einfach sicher, dass Sie die entsprechenden Änderungen an den if-elseif-else-Anweisungen vornehmen.
Sie können auch Iteratoren verwenden, wenn Sie möchten (ich weiß, dass sie in C ++ effizienter sind, ich weiß nicht, ob dies auch in Java zutrifft).
quelle
contains()
einer Schleife (wie Devenv vorschlägt) würde O (n + m) Zeit in Anspruch nehmen. Das Sortieren ist unnötig kompliziert und benötigt O (n log n + m log n + n) Zeit. Zugegeben, das reduziert sich auf O (n log n) Zeit, aber das ist immer noch schlimmer als die lineare Zeit und viel komplexer.Ich denke, Sie sollten a verwenden
Set
, um die Dateien zu halten, wenn Sie Schnittpunkte und Vereinigungen an ihnen vornehmen möchten. Dann können Sie verwenden Guava ‚s Sets Klasse zu tununion
,intersection
und das Filtern durch einePredicate
auch. Der Unterschied zwischen diesen Methoden und den anderen Vorschlägen besteht darin, dass alle diese Methoden träge Ansichten der Vereinigung, Schnittmenge usw. der beiden Mengen erzeugen . Apache Commons erstellt eine neue Sammlung und kopiert Daten in diese.retainAll
Ändert eine Ihrer Sammlungen, indem Sie Elemente daraus entfernen.quelle
So können Sie eine Schnittmenge mit Streams erstellen (denken Sie daran, dass Sie Java 8 für Streams verwenden müssen):
Ein Beispiel für Listen mit verschiedenen Typen. Wenn Sie eine Beziehung zwischen foo und bar haben und ein Balkenobjekt von foo erhalten können, können Sie Ihren Stream ändern:
quelle
Ich fand ListUtils für diesen Anwendungsfall sehr nützlich.
Verwenden Sie ListUtils aus org.apache.commons.collections, wenn Sie die vorhandene Liste nicht ändern möchten.
ListUtils.intersection(list1, list2)
quelle
Sie können commons-collection4 CollectionUtils verwenden
quelle
In Java 8 verwende ich einfache Hilfsmethoden wie diese:
quelle
Wenn die Objekte in der Liste hashbar sind (dh einen anständigen hashCode haben und gleich funktionieren), ist der schnellste Ansatz zwischen Tabellen ca. Bei einer Größe> 20 wird ein HashSet für die größere der beiden Listen erstellt.
quelle
Ich arbeitete auch an der ähnlichen Situation und erreichte hier die Suche nach Hilfe. Am Ende fand ich meine eigene Lösung für Arrays. ArrayList AbsentDates = new ArrayList (); // speichert Array1-Array2
Hinweis: Wenn Sie dies veröffentlichen, kann dies dazu beitragen, dass jemand diese Seite um Hilfe bittet.
quelle
Schnittpunkt zweier Listen verschiedener Objekte basierend auf dem gemeinsamen Schlüssel - Java 8
quelle
JDK8 + (wahrscheinlich beste Leistung)
Wenn Sie sich nicht für die Leistung interessieren und kleineren Code bevorzugen, verwenden Sie einfach:
quelle
Endgültige Lösung:
quelle
Zuerst kopiere ich alle Werte von Arrays in ein einzelnes Array, dann entferne ich doppelte Werte in das Array. Zeile 12, in der erklärt wird, ob dieselbe Zahl länger als die Zeit vorkommt, und ein zusätzlicher Müllwert in die Position "j" gebracht wird. Am Ende von Anfang bis Ende durchlaufen und prüfen, ob derselbe Müllwert auftritt, dann verwerfen.
quelle
ArrayList
um das Ergebnis der Vereinigung zu speichern.Integer
anstelle von in Betracht ziehenint
. Dann können Sienull
anstelle Ihres "Müllwerts" verwenden. "Garbage-Werte" oder "Sentinel-Werte" sind normalerweise eine schlechte Idee, da diese Werte möglicherweise noch in der Eingabe vorkommen.Nach dem Testen ist hier mein bester Kreuzungsansatz.
Schnellere Geschwindigkeit im Vergleich zum reinen HashSet-Ansatz. HashSet und HashMap unten haben eine ähnliche Leistung für Arrays mit mehr als 1 Million Datensätzen.
Beim Java 8 Stream-Ansatz ist die Geschwindigkeit bei Arrays mit einer Größe von mehr als 10 KB recht langsam.
Hoffe das kann helfen.
quelle
Die Methode keepAll () wird verwendet, um ein gemeinsames Element zu finden.
quelle
Wenn Sie Ihre Daten in Sets hätten, könnten Sie die
Sets
Klasse von Guava verwenden .quelle
Wenn die Zahl mit der von mir überprüften übereinstimmt, tritt sie mit Hilfe von "indexOf ()" zum ersten Mal auf oder nicht. Wenn die Zahl zum ersten Mal übereinstimmt, drucken Sie sie aus und speichern Sie sie in einer Zeichenfolge, damit sie beim nächsten Mal, wenn dieselbe Zahl übereinstimmt, gewonnen wird. ' t print, da die Bedingung aufgrund von "indexOf ()" falsch ist.
}}
quelle