Rheinwerk Computing < openbook >


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


Download:

- Listings, ca. 2,7 MB


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 17 Einführung in Datenstrukturen und Algorithmen
Pfeil 17.1 Listen
Pfeil 17.1.1 Erstes Listen-Beispiel
Pfeil 17.1.2 Auswahlkriterium ArrayList oder LinkedList
Pfeil 17.1.3 Die Schnittstelle List
Pfeil 17.1.4 ArrayList
Pfeil 17.1.5 LinkedList
Pfeil 17.1.6 Der Array-Adapter Arrays.asList(…)
Pfeil 17.1.7 ListIterator *
Pfeil 17.1.8 toArray(…) von Collection verstehen – die Gefahr einer Falle erkennen
Pfeil 17.1.9 Primitive Elemente in Datenstrukturen verwalten
Pfeil 17.2 Mengen (Sets)
Pfeil 17.2.1 Ein erstes Mengen-Beispiel
Pfeil 17.2.2 Methoden der Schnittstelle Set
Pfeil 17.2.3 HashSet
Pfeil 17.2.4 TreeSet – die sortierte Menge
Pfeil 17.2.5 Die Schnittstellen NavigableSet und SortedSet
Pfeil 17.2.6 LinkedHashSet
Pfeil 17.3 Java Stream-API
Pfeil 17.3.1 Deklaratives Programmieren
Pfeil 17.3.2 Interne versus externe Iteration
Pfeil 17.3.3 Was ist ein Stream?
Pfeil 17.4 Einen Stream erzeugen
Pfeil 17.4.1 Parallele oder sequenzielle Streams
Pfeil 17.5 Terminale Operationen
Pfeil 17.5.1 Die Anzahl der Elemente
Pfeil 17.5.2 Und jetzt alle – forEachXXX(…)
Pfeil 17.5.3 Einzelne Elemente aus dem Strom holen
Pfeil 17.5.4 Existenz-Tests mit Prädikaten
Pfeil 17.5.5 Einen Strom auf sein kleinstes bzw. größtes Element reduzieren
Pfeil 17.5.6 Einen Strom mit eigenen Funktionen reduzieren
Pfeil 17.5.7 Ergebnisse in einen Container schreiben, Teil 1: collect(…)
Pfeil 17.5.8 Ergebnisse in einen Container schreiben, Teil 2: Collector und Collectors
Pfeil 17.5.9 Ergebnisse in einen Container schreiben, Teil 3: Gruppierungen
Pfeil 17.5.10 Stream-Elemente in ein Array oder einen Iterator übertragen
Pfeil 17.6 Intermediäre Operationen
Pfeil 17.6.1 Element-Vorschau
Pfeil 17.6.2 Filtern von Elementen
Pfeil 17.6.3 Statusbehaftete intermediäre Operationen
Pfeil 17.6.4 Präfix-Operation
Pfeil 17.6.5 Abbildungen
Pfeil 17.7 Zum Weiterlesen
 

Zum Seitenanfang

17.4    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>

versionedStream() (ab Java 10)

Stream<JarEntry>

Tabelle 17.1    Methoden, die Stream-Exemplare liefern

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

Stream.ofXXX(…)

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 ein Array von zehn Zufallszahlen nach Normalverteilung:

Random random = new Random();

double[] randoms = Stream.generate( random::nextGaussian )

.limit( 10 ).mapToDouble( e -> e ).toArray();

System.out.println( Arrays.toString( randoms ) );

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 mit 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.

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 Ganzahl-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

17.4.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 17.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: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Objektorientierte Programmierung

Objektorientierte Programmierung




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

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2021

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