Java Blog

Präfix-Operation der Stream-API

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(…):

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.