Gibt es einen eleganteren Weg, ein zufälliges nicht verwendetes Objekt aus der Liste mit Java 8 zu erhalten?

8

Zu refaktorierende Funktion ...

%Vor%

Funktion könnte so verwendet werden ...

%Vor%

Bearbeiten: Gesammelte vorgeschlagene Implementierungen und getestete Effizienz, indem sie gegen Personenlisten ausgeführt werden.

edit2: Fehlende equals-Methode zur Person-Klasse hinzugefügt.

%Vor%

Ergebnisse:

%Vor%

Fazit

Wenn die Listengröße 10000 Elemente erreicht, ist bisher nur die Implementierung von Schaffner nutzbar.

Und weil es ziemlich einfach zu lesen ist, werde ich es als die eleganteste Lösung wählen.

    
Ari Aaltonen 20.12.2017, 20:03
quelle

3 Antworten

3

Sie sollten HashSet s verwenden, um die Leistung zu verbessern:

%Vor%

Damit werden Elemente aus dem all -Satz entfernt, wenn sie zum used -Satz gehören. Wenn Set.removeIf und Set.contains verwendet werden, ist die Entfernung von Elementen optimal. Dann wird eine zufällige Anzahl von Elementen in der resultierenden Menge übersprungen, und schließlich wird das nächste Element der Menge zurückgegeben.

Ein anderer Ansatz besteht darin, die all -Liste zuerst zu mischen und dann einfach zu iterieren und das erste Element zurückzugeben, das nicht zu used set gehört:

%Vor%

EDIT: Wenn ich den letzten Codeschnipsel überprüfe, merke ich, dass es nicht nötig ist, die ganze Liste zu mischen. Stattdessen können Sie die Indizes der allItems -Liste zufallsgenerieren und das erste Element zurückgeben, das nicht zu used set gehört:

%Vor%     
Federico Peralta Schaffner 21.12.2017, 02:52
quelle
4

Ich kann mir das vorstellen, aber keine Ahnung, wie es im Vergleich zu Ihrer bestehenden Lösung skalieren wird:

%Vor%

Beachten Sie, dass sorted eine stateful -Operation ist, also wird das gesamte "diff" sortiert, aber Sie erhalten nur ein Element daraus. Auch Ihr Comparator ist falsch, für die gleichen zwei Werte o1 und o2 könnten Sie sagen, dass sie unterschiedlich sind - dies kann auf mysteriöse Weise brechen.

    
Eugene 20.12.2017 21:02
quelle
1

Die Comparator , die du an die Operation sorted intermediate weitergegeben hast, scheint eine falsche und seltsame Methode zu sein, trotzdem ein Comparator für meine Augen zu verwenden; Das bezieht sich auf das, was @Eugene in seinem Beitrag erwähnt hat.

Ich würde Ihnen daher empfehlen, jede Art von Fallstricken zu vermeiden und immer eine API so zu verwenden, wie sie verwendet werden soll; nichts mehr.

wenn Sie wirklich ein zufälliges Element aus der Liste wollen; Die einzige Möglichkeit, die möglich ist, besteht darin, alle eindeutigen -Elemente der beiden Listen zu finden. also können wir die Geschwindigkeit in diesem Aspekt nicht verbessern.

sobald dies geschehen ist, müssen wir einfach eine zufällige ganze Zahl innerhalb des Bereichs der Liste erzeugen, die die verschiedenen Elemente und den Index enthält, vorausgesetzt, dass mindestens ein Element darin enthalten ist.

Obwohl ich zugeben muss, dass es wahrscheinlich bessere Möglichkeiten gibt, die vorliegende Aufgabe ohne die Verwendung von Streams zu erfüllen; Hier ist, wie ich Ihren Code leicht geändert habe, um den Missbrauch von .sorted((o1, o2) -> new Random().nextInt(2) - 1) zu entfernen.

%Vor%     
Aominè 20.12.2017 22:24
quelle

Tags und Links