Kommissionierung Elemente einer Liste, bis die Bedingung erfüllt ist mit Java 8-Lambdas
Ich versuche, um meine Meinung zu glauben, dass die funktionelle Art und Weise und vor kurzem konfrontiert, eine situation, in die ich brauchte, um abholen Elemente aus einer Liste aus, bis eine Bedingung erfüllt ist, und ich konnte nicht finden einen einfachen, natürlichen Weg, dies zu erreichen. Offensichtlich bin ich immer noch lernen.
Sagen, dass ich diese Liste:
List<String> tokens = Arrays.asList("pick me", "Pick me", "pick Me",
"PICK ME", "pick me and STOP", "pick me", "pick me and Stop", "pick me");
//In a non lambdas was you would do it like below
List<String> myTokens = new ArrayList<>();
for (String token : tokens) {
myTokens.add(token);
if (token.toUpperCase().endsWith("STOP")) {
break;
}
}
Vielen Dank im Voraus für Eure inputs
HINWEIS:
Vor der Veröffentlichung dieses lese ich Limit ein Strom durch ein Prädikat, aber ich konnte nicht sehen, wie ich das anpassen kann, dass die Antwort auf mein problem. Jede Hilfe wäre geschätzt danke.
- Ich habe gelesen, dass die Frage vorher veröffentlichte ich meine, aber ich dachte und denke immer noch, dass java würde einiges aus der box, dies zu erreichen. Etwas sagen wie
myTokens = tokens.stream().collect(toListWhile(...))
Oder eine schöne und einfache Möglichkeit für die UmsetzungtoListWhile()
benutzerdefinierte collector - Ich glaube nicht, dass es ein einzelner Betrieb in die Streams API, die würden davon ausgehen, geordneter Strom, und nicht für eine ungeordnete einem. So ist Ihr Betrieb vorstellen.
- mögliche Duplikate von Limit ein Strom durch ein Prädikat
- Dies ist nicht eine exakte Kopie, wie hier der OP will das STOP-element als auch. Es ist ein etwas anderes problem.
takeWhile
ist eigentlich so etwas wie dieses. JavaDoc-statement für ungeordnete streams ist besonders schön! Eine beliebige Teilmenge, sic! Meiner Meinung nach wäre es wirklich besser, wenn er eine exception wirft...- Ah, also sind Sie wieder hinzufügen---viele, wenn diese waren geplant, vor dem release von Java 8, aber dann fallen gelassen. Java hat in der Regel fail-fast-Semantik im Gegensatz zu GIGO. Dies ist sicher zum generieren einer Menge von sprachlos, SO Fragen.
- Es ist eine gute und interessante Frage, aber ich Stimme nicht mit seiner Prämisse. Ich glaube nicht, dass streams sind inteded verwendet werden, für das, was Sie versuchen, Sie zu benutzen. Vor allem, weil Ihr Betrieb hängt von den stream bestellt und, höchstwahrscheinlich, nicht parallelisiert. Was ich denke, Sie tun sollten, ist manuell (stream-weniger) bauen Sie eine gültige Sammlung und dann zu streamen, um es zu verarbeiten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer option verwendet einen Sammler, so daß zwei Funktionen, fügt strings Listen und anderen Listen kombiniert, die zuvor möglicherweise parallel angelegt. Für jedes it-fügt die Zeichenkette oder die gesamte Liste nur, wenn die Vorherige partielle Ausgabe endet nicht mit einem element endet mit STOP:
"STOP"
. Dies könnte problematisch sein, wenn Sie sehr lange (oder unbegrenzt) stream.Collector
statt.peek
. Eigentlich ist es nie garantiert, dassfindFirst
wird, Stoppt der zugrunde liegenden stream processing genau, wenn die Lösung gefunden ist (auch für sequentielle streams). Versuchen Sie ersetzentokens.stream()
mitStream.of(tokens).flatMap(List::stream)
. Es ist auch vollkommen legal Strom, der produziert die gleichen Elemente, aber Ihre Lösung funktioniert nicht mit ihm. Stream-API ist hart.In JDK9 es wird eine neue
Stream
Betrieb namenstakeWhile
, die die Sache ähnlich zu dem, was Sie brauchen. Ich zurück portiert Sie diesen Vorgang, um meine StreamEx Bibliothek, so können Sie es auch in Java-8:Leider ist es nicht die
"STOP"
element selbst, so dass der zweite Durchlauf ist notwendig, um es manuell hinzufügen:Beachten Sie, dass beide
takeWhile
undfindFirst
sind Kurzschluss-Operationen (Sie wird nicht die gesamte Eingabe-stream, wenn nicht erforderlich), so können Sie verwenden Sie sehr lange oder sogar unendliche streams.Jedoch mit StreamEx kann man es lösen in single-pass über den trick mit
groupRuns
. DiegroupRuns
Methode Gruppen angrenzenden Stream-Elemente, um dieList
basierend auf dem angegebenen Prädikat, das angibt, ob zwei benachbarte Elemente gruppiert werden sollen oder nicht. Wir sollten in Betracht ziehen, dass die Gruppe endet mit dem element mit"STOP"
. Dann brauchen wir nur, bis die erste Gruppe:Diese Lösung wird auch nicht extra Arbeit, wenn die erste Gruppe fertig ist.
takeWhile
Betrieb ist sequentieller Natur. Es ist nicht so einfach zu parallelisieren ist es richtig. Wahrscheinlich war das der Grund, warum es nicht enthalten war in JDK 8.filter
die würden auch wieder einige Teilmenge. Mein backport Umsetzung ist ziemlich lahmAbstractSpliterator
Unterklasse mit Standard -trySplit
: ich habe beschlossen, dass spezielle parallele Handhabung ist Verschwendung von Zeit.takeWhile
ist ja meist nutzlos für die konventionelle Sammlung-basierte Probleme, die wir sehen, eine Menge. Es stellt sich heraus, nützlich zu sein, wenn das Prädikat basiert auf externen Zustand, z.B. Verarbeitung von einem Strom von Ereignissen für eine bestimmte Zeit.takeWhile
JavaDoc...Wenn Sie wirklich verwenden müssen, Streams API, halten Sie es einfach und verwenden Sie einen Strom von Indizes:
Oder eine neue
List
aus der Unterliste wenn Sie möchten, eine unabhängige Kopie, die nicht unterstützt von der ursprünglichen Liste.Mit streng nur Java 8 API:
Können Sie sich dann spezialisieren Sie folgende Möglichkeiten:
Für Gewässer
Für Sammlungen
Obwohl die oben genannten Antworten sind vollkommen gültig, die Sie benötigen, um sammeln und/oder pre-fetch der Elemente vor der Verarbeitung (beides kann ein Problem sein, wenn der Stream sehr lange).
Für meine muss habe ich daher angepasst Louis ' Antwort auf die Frage hingewiesen, von Julian und angepasst, um zu halten der stop/break-Element. Finden Sie die
keepBreak
parameter ::Verwendung:
Haftungsausschluss: ich bin mir nicht 100% sicher, dass dies funktionieren wird auf parallel (die neue Stream ist sicherlich nicht parallel) oder nicht-sequentielle streams. Bitte kommentieren/Bearbeiten, wenn Sie haben einige Hinweise auf diesem.
takeUntil
nichttakeWhile
. Sie sind komplette Gegensätze