Rheinwerk Computing < openbook >


 
Inhaltsverzeichnis
Materialien zum Buch
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Arrays und ihre Anwendungen
5 Der Umgang mit Zeichen und Zeichenketten
6 Eigene Klassen schreiben
7 Objektorientierte Beziehungsfragen
8 Schnittstellen, Aufzählungen, versiegelte Klassen, Records
9 Ausnahmen müssen sein
10 Geschachtelte Typen
11 Besondere Typen der Java SE
12 Generics<T>
13 Lambda-Ausdrücke und funktionale Programmierung
14 Architektur, Design und angewandte Objektorientierung
15 Java Platform Module System
16 Die Klassenbibliothek
17 Einführung in die nebenläufige Programmierung
18 Einführung in Datenstrukturen und Algorithmen
19 Einführung in grafische Oberflächen
20 Einführung in Dateien und Datenströme
21 Einführung ins Datenbankmanagement mit JDBC
22 Bits und Bytes, Mathematisches und Geld
23 Testen mit JUnit
24 Die Werkzeuge des JDK
A Java SE-Module und Paketübersicht
Stichwortverzeichnis


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil 18 Einführung in Datenstrukturen und Algorithmen
Pfeil 18.1 Listen
Pfeil 18.1.1 Erstes Listen-Beispiel
Pfeil 18.1.2 Auswahlkriterium ArrayList oder LinkedList
Pfeil 18.1.3 Die Schnittstelle List
Pfeil 18.1.4 ArrayList
Pfeil 18.1.5 LinkedList
Pfeil 18.1.6 Der Array-Adapter Arrays.asList(…)
Pfeil 18.1.7 ListIterator *
Pfeil 18.1.8 toArray(…) von Collection verstehen – die Gefahr einer Falle erkennen
Pfeil 18.1.9 Primitive Elemente in Datenstrukturen verwalten
Pfeil 18.2 Mengen (Sets)
Pfeil 18.2.1 Ein erstes Mengen-Beispiel
Pfeil 18.2.2 Methoden der Schnittstelle Set
Pfeil 18.2.3 HashSet
Pfeil 18.2.4 TreeSet – die sortierte Menge
Pfeil 18.2.5 Die Schnittstellen NavigableSet und SortedSet
Pfeil 18.2.6 LinkedHashSet
Pfeil 18.3 Assoziative Speicher
Pfeil 18.3.1 Die Klassen HashMap und TreeMap
Pfeil 18.3.2 Einfügen und Abfragen des Assoziativspeichers
Pfeil 18.4 Java-Stream-API
Pfeil 18.4.1 Deklaratives Programmieren
Pfeil 18.4.2 Interne versus externe Iteration
Pfeil 18.4.3 Was ist ein Stream?
Pfeil 18.5 Einen Stream erzeugen
Pfeil 18.5.1 Parallele oder sequenzielle Streams
Pfeil 18.6 Terminale Operationen
Pfeil 18.6.1 Die Anzahl der Elemente
Pfeil 18.6.2 Und jetzt alle – forEach*(…)
Pfeil 18.6.3 Einzelne Elemente aus dem Strom holen
Pfeil 18.6.4 Existenztests mit Prädikaten
Pfeil 18.6.5 Einen Strom auf sein kleinstes bzw. größtes Element reduzieren
Pfeil 18.6.6 Einen Strom mit eigenen Funktionen reduzieren
Pfeil 18.6.7 Ergebnisse in einen Container schreiben, Teil 1: collect(…)
Pfeil 18.6.8 Ergebnisse in einen Container schreiben, Teil 2: Collector und Collectors
Pfeil 18.6.9 Ergebnisse in einen Container schreiben, Teil 3: Gruppierungen
Pfeil 18.6.10 Stream-Elemente in ein Array oder einen Iterator übertragen
Pfeil 18.7 Intermediäre Operationen
Pfeil 18.7.1 Element-Vorschau
Pfeil 18.7.2 Filtern von Elementen
Pfeil 18.7.3 Statusbehaftete intermediäre Operationen
Pfeil 18.7.4 Präfix-Operation
Pfeil 18.7.5 Abbildungen
Pfeil 18.8 Zum Weiterlesen
 

Zum Seitenanfang

18.5    Einen Stream erzeugen Zur vorigen ÜberschriftZur nächsten Überschrift

Das Paket java.util.stream deklariert diverse Typen rund um Streams. Im Zentrum steht für Objektströme eine generisch deklarierte Schnittstelle Stream. Ein konkretes Exemplar wird immer von einer Datenquelle erzeugt. Unter anderem stehen folgende Stream-Erzeuger zur Verfügung:

Typ

Methode

Rückgabe

Collection<E>

stream()

Stream<E>

Arrays

stream(T[] array) (statisch)

Stream<T>

stream(T[] array, int start, int end) (statisch)

Stream<T>

Stream

empty() (statisch)

Stream<T>

of(T… values) (statisch)

Stream<T>

of(T value) (statisch)

Stream<T>

generate(Supplier<T> s)(statisch)

Stream<T>

iterate(T seed,

UnaryOperator<T> f)(statisch)

Stream<T>

iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) (statisch)

Stream<T>

ofNullable(T t) (statisch)

Stream<T>

Optional<T>

Stream()

Stream<T>

Scanner

tokens() (ab Java 9)

Stream<String>

String

lines() (ab Java 11)

Stream<String>

Files

lines(Path path)

Stream<String>

lines(Path path, Charset cs)

Stream<String>

list(Path dir)

Stream<Path>

walk(Path start, FileVisitOption… options)

Stream<Path>

walk(Path start, int maxDepth, FileVisitOption… options)

Stream<Path>

find(Path start, int maxDepth, BiPredicate<Path,BasicFileAttributes> matcher, FileVisitOption… options)

Stream<Path>

BufferedReader

lines()

Stream<String>

Pattern

splitAsStream(CharSequence input)

Stream<String>

ZipFile

stream()

Stream<? extends ZipEntry>

JarFile

stream()

Stream<JarEntry>

Stream<JarEntry>

versionedStream() (ab Java 10)

Tabelle 18.1     Methoden, die Stream-Exemplare liefern

Die Methode Stream.empty() liefert wie erwartet einen Strom ohne Elemente.

Stream.of*(…)

Stream hat einige Fabrikmethoden für neue Ströme (etwa of(…)), alles andere sind Objektmethoden anderer Klassen, die Ströme liefern. Die of(…)-Methoden sind als statische Schnittstellenmethoden von Stream implementiert, und of(T… values) ist nur eine Fassade für Arrays.stream(values). Die Methode static <T> Stream<T> ofNullable(T t) liefert, wenn t == null ist, einen leeren Stream; und wenn t != null ist, liefert sie einen Stream mit genau dem Element t. Die Methode ist nützlich für Teilströme, die integriert werden.

[zB]  Beispiel

Produziere einen Stream aus gegebenen Ganzzahlen, entferne die Vorzeichen, sortiere das Ergebnis und gibt es aus:

Stream.of( -4, 1, -2, 3 )

.map( Math::abs )

.sorted()

.forEach( System.out::println ); // 1 2 3 4

Stream.generate(…)

generate(…) produziert Elemente aus einem Supplier; der Stream ist unendlich.

[zB]  Beispiele

Erzeuge einen Strom von Fibonacci-Zahlen[ 254 ](https://de.wikipedia.org/wiki/Fibonacci-Folge):

class FibSupplier implements Supplier<BigInteger> {

private final Queue<BigInteger> fibs =

new LinkedList<>( Arrays.asList( BigInteger.ZERO, BigInteger.ONE ) );

@Override public BigInteger get() {

fibs.offer( fibs.remove().add( fibs.peek() ) );

return fibs.peek();

}

};

Stream.generate( new FibSupplier() )

.limit( 1000 ).forEach( System.out::println );

Die Implementierung nutzt keinen Lambda-Ausdruck, sondern eine altmodische Klassenimplementierung, da wir uns für die Fibonacci-Folgen die letzten beiden Elemente merken müssen. Sie speichert eine LinkedList, die als Queue genutzt wird. Bei der Anfrage an ein neues Element nehmen wir das erste Element heraus, sodass das zweite nachrutscht, und addieren es zu dem Kopfelement, was die Fibonacci-Zahl ergibt. Die hängen wir im zweiten Schritt hinten an und geben sie zurück. Parallele Zugriffe sind nicht gestattet. Der Stream ist zunächst unendlich groß, wird dann aber mit limit(…) auf 1.000 Elemente beschränkt.

Stream.iterate(…)

Die zwei statischen iterate(…)-Methoden generieren einen Stream aus einem Startwert und einer Funktion, die das nächste Element produziert. Bei iterate(T seed, UnaryOperator<T> f) ist der Strom unendlich, bei der zweiten (in Java 9 hinzugekommenen) Methode iterate(…, Predicate<? super T> hasNext, …) beendet ein erfülltes Prädikat den Strom und erinnert an eine klassische for-Schleife. Der Abbruch über ein Prädikat ist sehr flexibel, denn bei der ersten iterate(…)-Methode ist der Strom unendlich, und so folgt oftmals ein limit(…) oder takeWhile(…) zum Limitieren der Elemente.

[zB]  Beispiel 1

Produziere Permutationen eines Strings.

UnaryOperator<String> shuffleOp = s -> {

char[] chars = s.toCharArray();

for ( int index = chars.length - 1; index > 0; index-- ) {

int rndIndex = ThreadLocalRandom.current().nextInt( index + 1 );

if ( index == rndIndex ) continue;

char c = chars[ rndIndex ];

chars[ rndIndex ] = chars[ index ];

chars[ index ] = c;

}

return new String( chars );

};

String text = "Sie müssen nur den Nippel durch die Lasche ziehn";

Stream.iterate( text, shuffleOp ).limit( 10 ).forEach( System.out::println );

Die Ganzzahl-Zufallszahlen stammen dies Mal nicht von einen Random-Objekt, sondern von ThreadLocalRandom. Diese spezielle Klasse ist mit dem aktuellen Thread verbunden und kann ebenfalls einzelne Zufallszahlen oder einen Strom liefern. Bei Nebenläufigkeit bietet diese Variante eine bessere Performance.

[zB]  Beispiel 2

Erzeuge einen endlosen Stream aus BigInteger-Objekten, der bei 10.000.000 beginnt und in Einerschritten weitergeht, bis mit hoher Wahrscheinlichkeit eine Primzahl erscheint und der Strom damit endet:

Predicate<BigInteger> isNotPrime = i -> ! i.isProbablePrime( 10 );

UnaryOperator<BigInteger> incBigInt = i -> i.add( BigInteger.ONE );

Stream.iterate( BigInteger.valueOf( 10_000_000 ), isNotPrime, incBigInt )

.forEach( System.out::println );
 

Zum Seitenanfang

18.5.1    Parallele oder sequenzielle Streams Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Stream kann parallel oder sequenziell sein. Das heißt, es ist möglich, dass Threads gewisse Operationen nebenläufig durchführen, wie zum Beispiel die Suche nach einem Element. Stream liefert über isParallel() die Rückgabe true, wenn ein Stream Operationen nebenläufig durchführt.

Alle Collection-Datenstrukturen können mit der Methode parallelStream() einen potenziell nebenläufigen Stream liefern.

Typ

Methode

Rückgabe

Collection

parallelStream()

Stream<E>

Collection

stream()

Stream<E>

Tabelle 18.2     Parallele und nichtparallele Streams von jeder »Collection« erfragen

Jeder parallele Stream lässt sich mithilfe der Stream-Methode sequential() in einen sequenziellen Stream konvertieren. Parallele Streams nutzen intern das Fork-&-Join-Framework, doch sollte nicht automatisch jeder Stream parallel sein, da das nicht zwingend zu einem Performance-Vorteil führt. Wenn zum Beispiel keine Parallelisierung möglich ist, bringt es wenig, Threads einzusetzen.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java ist auch eine Insel Java ist auch eine Insel

Jetzt Buch bestellen


 Buchempfehlungen
Zum Rheinwerk-Shop: Captain CiaoCiao erobert Java

Captain CiaoCiao erobert Java




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Spring Boot 3 und Spring Framework 6

Spring Boot 3 und Spring Framework 6




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2024

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.

Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de



Cookie-Einstellungen ändern