Ich habe eine Liste vom Typ Integer, zB:
[1, 1, 2, 3, 3, 3]
Ich möchte eine Methode, um alle Duplikate zurückzugeben, z.
[1, 3]
Was ist der beste Weg, dies zu tun?
java
collections
am frischesten
quelle
quelle
Antworten:
Das Verfahren
add
vonSet
liefert einen boolean , ob ein Wert bereits vorhanden ist (true , wenn es nicht vorhanden ist , falsch , wenn es bereits vorhanden ist , siehe Set - Dokumentation ).Durchlaufen Sie einfach alle Werte:
quelle
for (Integer yourInt
, um unnötiges Boxen und Unboxing zu vermeiden, zumal Ihre Eingabe bereitsInteger
s enthält .HashSet
Sie auch den Lastfaktor berücksichtigen müssen, z. B. wenn Sie eine Anfangskapazität von angeben100
, weil Sie diese Anzahl von Elementen hinzufügen möchten, wird dieser auf die nächste Potenz von 2 (128
) gerundet , was dies impliziert Mit dem Standardladefaktor von0.75f
wird der Größenänderungsschwellenwert festgelegt96
, sodass eine Größenänderung vorgenommen wird, bevor Sie100
Elemente hinzugefügt haben . Zum Glück ist die Größenänderung nicht mehr so teuer. Mit aktuellen JREs wird die Größenänderung nicht mehr erneut aufbereitet, sondern die Elemente werden nur basierend auf dem relevanten Bit auf ihre beiden möglichen Ergebnispositionen verteilt.Ich brauchte auch dafür eine Lösung. Ich habe die Lösung von Leifg verwendet und sie generisch gemacht.
quelle
Ich nahm John Stricklers Lösung und machte sie neu, um die in JDK8 eingeführte Streams-API zu verwenden:
quelle
distinct()
Methode ist ebenfalls statusbehaftet. Ich kann mir keine effiziente (O (n)) eindeutige Operation vorstellen, die nicht zustandsbehaftet ist.Hier ist eine Lösung mit Streams mit Java 8
Sie sehen nur, ob die Häufigkeit dieses Objekts mehr als einmal in Ihrer Liste enthalten ist. Rufen Sie dann .distinct () auf, um nur eindeutige Elemente in Ihrem Ergebnis zu haben
quelle
Collections::frequency
ist O (n). Es muss die gesamte Sammlung durchlaufen, um die Häufigkeit eines Artikels zu ermitteln. Und wir nennen dies einmal für jeden Artikel in der Sammlung, wodurch diese Schnipsel entstehenO(n^2)
. Sie werden den Unterschied in jeder Sammlung von mehr als einer Handvoll Elementen bemerken. Ich würde dies niemals im eigentlichen Code verwenden.Java 8 Basislösung:
quelle
Natürlich können Sie mit ihnen machen, was Sie wollen (dh in ein Set einfügen, um eine eindeutige Liste doppelter Werte zu erhalten), anstatt zu drucken ... Dies hat auch den Vorteil, dass auch die Position doppelter Elemente aufgezeichnet wird.
quelle
Verwenden von Guava unter Java 8
quelle
Das funktioniert auch:
quelle
Sie können so etwas verwenden:
quelle
int
hier nicht anfangen, als Variablentyp zu verwenden. Dies bedeutet, dass für jede einzelne Iteration eine Ganzzahl einmal und ein Int viermal entpackt wird!Lambas könnte eine Lösung sein
quelle
Verwenden Sie eine MultiMap, um jeden Wert als Schlüssel / Wertesatz zu speichern. Durchlaufen Sie dann die Schlüssel und suchen Sie diejenigen mit mehreren Werten.
quelle
Wenn Sie Eclipse-Sammlungen verwenden , funktioniert dies:
Update: Ab Eclipse Collections 9.2 können Sie jetzt verwenden
selectDuplicates
Sie können auch primitive Sammlungen verwenden, um dies zu erreichen:
Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.
quelle
quelle
Ähnlich wie bei einigen Antworten hier, aber wenn Sie Duplikate basierend auf einer Eigenschaft suchen möchten:
quelle
Erstellen Sie eine
Map<Integer,Integer>
, iterieren Sie die Liste. Wenn sich ein Element in der Karte befindet, erhöhen Sie seinen Wert. Fügen Sie es andernfalls mit Schlüssel = 1zur Karte hinzu. Iterieren Sie die Karte und fügen Sie alle Elemente mit Schlüssel> = 2 zu den Listen hinzu
quelle
Kompakte generierte Version der Top-Antwort, außerdem leerer Scheck hinzugefügt und vorbelegt Set-Größe:
quelle
tempSet
mit ,listSize
wenn notwendig. Dies ist eine kleine Optimierung, aber ich mag es.Ich nahm Sebastians Antwort und fügte einen keyExtractor hinzu -
quelle
Eine thread-sichere Alternative ist folgende:
quelle
Versuchen Sie dies, um doppelte Elemente in der Liste zu finden:
quelle
Dies sollte für sortiert und unsortiert funktionieren.
quelle
Dies ist ein Problem, bei dem funktionale Techniken glänzen. Zum Beispiel ist die folgende F # -Lösung sowohl klarer als auch weniger fehleranfällig als die beste zwingende Java-Lösung (und ich arbeite täglich sowohl mit Java als auch mit F #).
Natürlich geht es bei dieser Frage um Java. Mein Vorschlag ist daher, eine Bibliothek zu verwenden, die Java Funktionsfunktionen bietet. Zum Beispiel könnte es mit meiner eigenen Bibliothek wie folgt gelöst werden (und es gibt auch einige andere, die einen Blick wert sind):
quelle
quelle
quelle
Dies wäre eine gute Methode, um doppelte Werte zu finden, ohne Set zu verwenden.
Angenommen, Sie möchten eine Methode, die Ihnen eine eindeutige Liste zurückgibt. Wenn Sie also eine Liste übergeben, in der Elemente mehr als einmal vorkommen, erhalten Sie eine Liste mit unterschiedlichen Elementen.
quelle
Und Version, die
commons-collections
CollectionUtils.getCardinalityMap
Methode verwendet:`` `
quelle
Wie wäre es mit diesem Code -
quelle
Nur für den Fall, dass Sie sowohl das Duplikat als auch das Nicht-Duplikat einschließen möchten. Grundsätzlich ist die Antwort der richtigen Antwort ähnlich, aber anstatt von einem Teil zurückzukehren, wenn nicht Teil, geben Sie den anderen Teil zurück
Verwenden Sie diesen Code (ändern Sie den gewünschten Typ)
quelle
Allgemeinere Methode als Variante von https://stackoverflow.com/a/52296246
quelle
Wenn Sie den Maximalwert kennen (zum Beispiel <10000), können Sie Platz für Geschwindigkeit opfern. Ich kann mich nicht an den genauen Namen dieser Technik erinnern.
Pseudocode:
quelle
Versuchen Sie einfach Folgendes:
Beispiel, wenn Listenwerte sind: [1, 2, 3, 4, 5, 6, 4, 3, 7, 8] doppeltes Element [3, 4].
quelle