Unter einem Präfix verstehen wir eine Teilfolge eines Streams, die beim ersten Element beginnt. Wir können mit limit(long) selbst einen Präfix generieren, doch im Allgemeinen geht es darum eine Bedingung zu haben, die alle Elemente eines Präfix-Streams erfüllen müssen, und wenn es für ein Element nicht gilt, dann den Stream zu beenden. Java 9 deklariert für dafür zwei neue Methoden takeWhile(…) und dropWhile(…):
- default Stream<T> takeWhile(Predicate<? super T> predicate)
- default Stream<T> dropWhile(Predicate<? super T> predicate)
Die deutsche Übersetzung von takeWhile(…) wäre „nimm solange predicate gilt“ und dropWhile(…) „lass fallen, solange predicate gilt“.
Beispiel: Der Stream soll bei Eintreffen des Wortes „Trump“ sofort enden:
new Scanner( "Dann twitterte Trump am 7. Nov. 2012: " + "'It's freezing and snowing in New York--we need global warming!'" ) .useDelimiter( "\\P{Alpha}+" ).tokens() .takeWhile( s -> !s.equalsIgnoreCase( "trump" ) ) .forEach( System.out::println ); // Dann twitterte }
Der Stream soll nach dem längsten Präfix beginnen, nämlich dann, wenn eine Zahl negativ wurde:
Stream.of( 1, 2, -1, 3, 4, -1, 5, 6 ) .dropWhile( i -> i > 0 ) .forEach( System.out::println ); // -1 3 4 -1 5 6
Das Element, das das Prädikat erfüllt, ist selbst das erste Element im neuen Stream. Wir können es mit skip(1) überspringen.
Erfüllt schon bei takeWhile(…) das erste Element nicht das Prädikat ist die der Ergebnis-Stream leer, erfüllt kein Element die Bedingung ist das Ergebnis wie der Ursprungs-Stream. takeWhile(…) und dropWhile(…) können zusammen verwendet werden: so liefert Stream.of( 1, 2, -1, 3, 4, -1, 5, 6 ).dropWhile( i -> i > 0 ).skip( 1 ).takeWhile( i -> i > 0 ).forEach( System.out::println ); die Ausgaben 3 4.
Hinweis: Präfixe sind nur für geordnete Streams sinnvoll. Und wenn Streams parallel sind müssen sie für die Präfixberechnung wieder in Reihe gebracht werden, das ist eine eher teurer Operation.
So großes Sendungsbewusstsein das man selbst Code politisieren muss?
Es gibt oftmals in den Insel-Texten und Beispielen Bezüge zu Personen und Themen der Zeitgeschichte, sodass man später gut ablesen kann, in welcher Epoche welcher
Absatz geschrieben wurde und somit weiß, wann in etwa welches Feature in Java dazukam.