Klaus Kreft Selbstständig

Eine spezifische Spliterator-Implementierung für ImmutableList beseitigt Performanceeinschränkung.

Angelika Langer Selbstständig

Jede Klasse, die von dem Interface Collection abgeleitet ist, kann als Stream Source verwendet werden.

Wir wollen uns in diesem Beitrag ansehen, wie man eigene Datenabstraktionen als Sources für Java 8 Streams verwenden kann. So ist es möglich, die gesamte Stream-Funktionalität auf eigene Datenabstraktionen anzuwenden.

Mit Java 8 sind Streams Teil des JDK geworden, also Implementierungen der Interfaces Stream, IntStream, LongStream und DoubleStream, alle aus dem Package java.util.stream. Das JDK stellt mit Java 8 auch die Funktionalität zur Verfügung, um Streams aus JDK Collections, Arrays, CharSequences und einigen anderen Datenabstraktionen zu erzeugen. Typisch ist dabei, dass die Datenabstraktionen, die als Stream Sources dienen, jeweils eine Sequenz von Elementen eines gemeinsamen Datentyps repräsentieren. Bei CharSequences ist dies z. B. die Sequenz der Zeichen in der CharSequence. Der Stream erlaubt es dann, Funktionalität auf die Elemente der Sequenz anzuwenden. Ein Beispiel zeigt Listing 1.

String text = "A Stream is a sequence of elements supporting 
               sequential and parallel aggregate operations.";

long cnt = text.chars()
               .filter(i -> !Character.isSpaceChar(i))
               .count();

System.out.println("number of non-space characters: " + cnt);

Wir ermitteln, wie viele nicht leere Zeichen der String text enthält, indem wir aus text mit chars() einen IntStream erzeugen. Danach werden nur die nicht leeren Zeichen mit filter() durch den Filter gelassen und anschließend mit count() gezählt. Es mag auf den ersten Blick überraschend erscheinen, dass die Character eines Strings nicht als Source für einen CharStream dienen, sondern als IntStreams verarbeitet werden. Der Grund ist, dass es keinen CharStream gibt und deshalb der Stream des nächst größeren primitiven Typs verwendet wird, für den ein Stream-Typ existiert.

Das JDK stellt mit Java 8 bereits die Funktionalität zur Verfügung, aus einer CharSequence, also in unserem Beispiel einem String, einen Stream zu erzeugen. Im Folgenden wollen wir uns ansehen, was wir tun sollten, wenn wir aus einer eigenen Datenabstraktion einen Stream erzeugen wollen.

Um nicht extra für diesen Artikel eine eigene Datenabstraktion implementieren zu müssen, verwenden wir die ImmutableList aus der Guava-19.0-Bibliothek. ImmutableList ist eine abstrakte Klasse. Sie hat Factory-Methoden, die eine Instanz von RegularImmutableList erzeugen, wenn mehr als ein Element in der Liste ist. Die Klasse RegularImmutableList ist von außen nicht sichtbar, da sie protected im Package com.google.common.collect deklariert ist. Neben RegularImmutableList gibt es weitere Spezialisierungen von ImmutableList, für den Fall, dass die Liste ein oder kein Element enthält. Diese sind aber für unseren Artikel nicht weiter relevant.

Den vollständigen Artikel lesen Sie in der Ausgabe:

Java Magazin 10.16 - "Security agil verankern"

Alle Infos zum Heft
261507Datenströme und -abstraktionen in Java 8
X
- Gib Deinen Standort ein -
- or -