Die Java Stream API. Funktionale Programmierung mit der Stream API des JDK 1.8. Prof. Dr. Nikolaus Wulff



Ähnliche Dokumente
Programmierkurs Java

Objektorientierte Programmierung

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Einführung in die Java- Programmierung

Übersicht Programmablaufsteuerung

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Erwin Grüner

Java Kurs für Anfänger Einheit 5 Methoden

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Import und Export von Übergängern

Institut für Programmierung und Reaktive Systeme 25. August Programmier-Labor Übungsblatt. int binarysearch(int[] a, int x),

myfactory.go! - Verkauf

Einführung in die Programmierung

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Objektbasierte Entwicklung

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

In vergleichsbasierten Suchbäumen wird nicht in Schlüssel hineingeschaut.

Java Einführung Collections

Mit dem Tool Stundenverwaltung von Hanno Kniebel erhalten Sie die Möglichkeit zur effizienten Verwaltung von Montagezeiten Ihrer Mitarbeiter.

Delegatesund Ereignisse

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

Bedienungsanleitung: Onlineverifizierung von qualifiziert signierten PDF-Dateien

SUB-ID- VERWALTUNG MIT GPP SETUP-GUIDE FÜR PUBLISHER

Scala kann auch faul sein

SUDOKU - Strategien zur Lösung

Einführung in die Programmierung

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Melde- und Veröffentlichungsplattform Portal (MVP Portal) Hochladen einer XML-Datei

R ist freie Software und kann von der Website.

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

Wir arbeiten mit Zufallszahlen

IT-Basics 2. DI Gerhard Fließ

Erfahrungen mit Hartz IV- Empfängern

Grundlagen der Theoretischen Informatik, SoSe 2008

Wir machen neue Politik für Baden-Württemberg

1 Vom Problem zum Programm

Programmierung in C. Grundlagen. Stefan Kallerhoff

Deutsches Rotes Kreuz. Kopfschmerztagebuch von:

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Java-Programmierung mit NetBeans

Viele Bilder auf der FA-Homepage

Zwischenablage (Bilder, Texte,...)

1. Einführung Erstellung einer Teillieferung Erstellung einer Teilrechnung 6

Modellierung und Programmierung 1

Arbeiten mit UMLed und Delphi

Rundung und Casting von Zahlen

Funktionale Programmierung mit Haskell

Einführung in die objektorientierte Programmierung mit Java. Klausur am 19. Oktober 2005

Anwendertreffen 20./21. Juni

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Programmieren in C. Felder, Schleifen und Fließkommaarithmetik. Prof. Dr. Nikolaus Wulff

Mediator 9 - Lernprogramm

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Anton Ochsenkühn. amac BUCH VERLAG. Ecxel für Mac. amac-buch Verlag

Ein Blick voraus. des Autors von C++: Bjarne Stroustrup Conrad Kobsch

Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])

2. Semester, 2. Prüfung, Lösung

Kurzanleitung für Verkäufer

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Access [basics] Rechnen in Berichten. Beispieldatenbank. Datensatzweise berechnen. Berechnung im Textfeld. Reporting in Berichten Rechnen in Berichten

Planung für Organisation und Technik

Studentische Lösung zum Übungsblatt Nr. 7

Softwarelösungen: Versuch 4

4 Aufzählungen und Listen erstellen

CMS.R. Bedienungsanleitung. Modul Cron. Copyright CMS.R Revision 1

Angewandte Mathematik und Programmierung

Grundbegriffe der Informatik

1. Einführung. 2. Alternativen zu eigenen Auswertungen. 3. Erstellen eigener Tabellen-Auswertungen

Softwareentwicklungspraktikum Sommersemester Grobentwurf

Java: Vererbung. Teil 3: super()

Programmieren für Ingenieure Sommer Ein Rechner. Rechner sind überall. Gerät, das mittels programmierbarer Rechenvorschriften Daten verarbeitet.

Vorstellung Microsoft Mathematics 4.0

Über Arrays und verkettete Listen Listen in Delphi

GEONET Anleitung für Web-Autoren

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

2A Basistechniken: Weitere Aufgaben

1 topologisches Sortieren

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Haben Sie über elektronisches Schließfachmanagement nachgedacht? Ein Schließfach ist ohne ein solides Schloss nicht komplett.

SMS/ MMS Multimedia Center

M. Graefenhan Übungen zu C. Blatt 3. Musterlösung

Feiertage in Marvin hinterlegen

Benutzung der LS-Miniscanner

Institut für Programmierung und Reaktive Systeme 26. April Programmieren II. 10. Übungsblatt

Automatisierung ( Fernsteuerung ) von Excel unter Microsoft Windows Tilman Küpper (tilman.kuepper@hm.edu)

Anleitung über den Umgang mit Schildern

Anleitung für die Online-Bewerbung über LSF auf Lehrveranstaltungen aller Lehramtsstudiengänge

1. Adressen für den Serienversand (Briefe Katalogdruck Werbung/Anfrage ) auswählen. Die Auswahl kann gespeichert werden.

5. Tutorium zu Programmieren

Graphic Coding. Klausur. 9. Februar Kurs A

Objektorientierte Programmierung für Anfänger am Beispiel PHP

MY-CAREER-HOMEPAGE.com

Allgemeines. Verschiedene Sprachkonzepte C-Sprachfamilie C-ähnliche Programmiersprachen Allgemeines zu C. #include <stdio.h>

Serienbrieferstellung in Word mit Kunden-Datenimport aus Excel

Anleitung für die Formularbearbeitung

EndTermTest PROGALGO WS1516 A

Transkript:

Die Java Stream API Funktionale Programmierung mit der Stream API des JDK 1.8 Prof. Dr. Nikolaus Wulff

Funktionale Programmierung Neben der Collection API mit default Methoden ist als weitere Neuerung eine Stream API ins JDK v1.8 integriert worden. Jede Java Collection liefert per default stream() Methode einen java.util.stream.stream zurück. Mittels eines Stream ist Funktionale Programmierung in Java gerade für große Datenmengen möglich. Während Collections reine Datenkontainer sind, verwenden Streams Algorithmen, die auf den Daten z.b. einer Collection effizient operieren. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 2

Stream Programmiermodel Die funktionale Stream Programmierung erfolgt im Prinzip in drei Schritten: 1. Der Erzeugung des Stream. 2. Einer Abfolge von Operationen für die Elemente. 3. Einer Abschließenden Terminierung mit Ergebnis. Quelle => Stream => OP 1 => OP 2 => => OP n => Ergebnis Die Abfolge der Operationen OP k auf den Daten lässt sich per Stream API sehr leicht parallel ausführen. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 3

Schleifenabarbeitung Eine Liste von Wörtern soll in Abhängigkeit von der Wortlänge auf der Konsole ausgegeben werden. Der Standardweg über einen Iterator sieht so aus: List<String> list =... Iterator<String> iterator = list.iterator(); while (iterator.hasnext()) { String s = iterator.next(); if (s.length()>wordlength) System.out.printf("%s %s \n", Thread.currentThread(), s); } Das Codefragment gibt alle Zeichenketten größer als die Variable wordlength auf der Konsole aus und zeigt auch an in welchem Thread dies geschieht. Eine Parallelisierung ist nur schwer möglich... Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 4

Moderne for-each-schleife Seit dem JDK v1.5 wird meistens die while gegen die modernere for-each Schleife ersetzt: List<String> list =... for (String s : list) { if (s.length()>wordlength) System.out.printf("%s %s \n", Thread.currentThread(), s); } Der Code sieht kompakter aus, der Compiler realisiert intern die while Schleife des vorherigen Beispiels. Die aufwändige Angabe der printf Anweisung lässt sich seit dem JDKv1.8 als Lambda Ausdruck kapseln. Consumer<Object> printer = s -> System.out.printf("%s %s \n", Thread.currentThread(), s.tostring()); Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 5

foreach Methode Seit dem JDKv1.8 besitzen alle Collections eine default foreach Methode zur Implementierung einer Schleife, die einen Consumer erwartet. List<String> list =... list.foreach((s) -> { if (s.length()>wordlength) printer.accept(s); }); Zwei Consumer per λ Ausdrücke Eine Parallelisierung der Aufgabe kann einfach durch einer andere Implemtierung der foreach Methode innerhalb einer spezialisierten Liste realisiert werden oder aber durch die Stream API. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 6

Stream per VarArgs Streams lassen sich direkt per Varargs erzeugen: Stream<String> stream = Stream.of("Die", "neue", "Stream", "API"); Hierzu bietet die Schnittstelle Stream die statische Methode of an mit der Signatur: static <T> Stream<T> of(t... values) Diese generische statische Schnittstellen Methode erlaubt eine einfache Konstruktion eines Stream. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 7

Streams aus Feldern Eine weitere Möglichkeit der Erzeugung eines Stream ist per Hilfsmethode aus der Klasses Arrays: String[] array = { "Die", "neue", "Stream", "API" }; Stream<String> stream = Arrays.stream(array); Für primitive Daten wie double oder int gibt es spezialisierte Stream Klassen, z.b. DoubleStream... Es ist somit möglich ein Stream direkt aus einem Feld oder per VarArgs zu erzeugen und per Collection, wie das nächste Beispiel zeigt. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 8

Von Collection zu Stream Jede Collection lässt sich in einen Stream überführen auf dem dann die Aufgaben abgearbeitet werden: List<String> list =... Stream<String> stream = list.stream(); stream.foreach((s) -> { if (s.length()>wordlength) printer.accept(s); }); Auch Streams stellen eine foreach Schleife zur Verfügung, ähnlich den Collections. Auf dem ersten Blick ist nicht viel gewonnen, doch Streams lassen sich verketten, erlauben effizientes Filtern, weitere Algorithmen und Parallelisierung. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 9

Stream mit Filter Jeder Stream hat eine filter Methode, die mittels eines Prädikats meist ein Lambda Ausdruck parameterisiert wird. List<String> list = Stream<String> stream = list.stream(); stream.filter(s -> s.length()>wordlength).foreach(s -> { printer.accept(s); }); filter ist der foreach Methode vorgeschaltet. Nur die Elemente, die der Filterbedingung genügen werden überhaupt in der Schleife ausgegeben. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 10

Stream mit Map Jeder Stream kennt eine funktionale Abbildung aller Elemente per map Funktion: List<String> list = Stream<String> stream = list.stream(); stream.filter(s -> s.length()>wordlength).map(s -> s.touppercase()).foreach(s -> { printer.accept(s); }); map und filter lassen sich hintereinander verketten. Sie liefern wieder einen Stream für weitere Verarbeitung zurück. So lässt sich effizient eine Pipes & Filter Architektur realisieren. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 11

Streams parallelisieren Stream lassen sich sehr elegant und für den Programmier fast transparent parallelisieren ohne das filter oder die foreach Schleife zu verändern: List<String> list = Stream<String> stream = list.parallelstream(); stream.filter(s -> s.length()>wordlength).foreach(s -> { printer.accept(s); }); Der Aufruf von parallelstream anstatt stream sorgt dafür das alle Stream-Operationen multithreaded ausgeführt werden. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 12

Stream nachträglich parallelisieren Auf der vorhergehenden Folie wurde der Stream parallel erzeugt, aber auch ein schon existierender Stream lässt sich nachträglich Parallelisieren per parallel Methode: List<String> list = Stream<String> stream = list.stream().parallel(); stream.filter(s -> s.length()>wordlength).foreach(s -> { printer.accept(s); }); Diese Methode liefert eine Stream Instanz zurück, die den ursprünglichen Stream parallel ausführt. Somit lässt sich ein sequentieller Algorithmus einfach und transparent parallelisieren. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 13

Stream Operationen Ein Stream stellt einen Satz von Operationen zur Verfügung, die sich mittels @FunctionalInterface parametrisieren lassen. Es gibt prinzipiell zwei Typen von Operationen: Intermediäre Stream-Operationen Diese modifizieren die Daten und liefern wieder einen Stream zurück, sie lassen sich daher verketten. Die Stream Verarbeitung wird weiter fortgesetzt. Terminale Stream-Operationen Ihr Aufruf stellt das Ende einer Stream Verarbeitungskette da und liefert das Endresultat. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 14

Intermediäre Operationen filter(predicate) Daten nach Prädicat gefiltert map(function) Datentransformation per Abbildung distinct() Stream um Dubletten bereinigt limit(long n) Stream wird auf Länge n begrenzt peek(consumer) Daten per Consumer verwenden skip(long n) die nächsten n Daten überspringen sorted() liefert Stream mit sortierten Daten Alle Intermediären Operationen liefern als Ergebnis wieder einen Stream zurück und lassen sich verketten. Sie arbeiten lazy, die Verarbeitung wird erst durch eine terminale Operation angestossen. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 15

Terminale Operationen collect(collector) Zusammenfassen von Daten count() Anzahl der Daten im Stream foreach(consumer) Schleife über alle Daten max/min(comperator) Maximum/Minimum reduce(binaryoperator) Reduktion der Daten Terminale Operationen sind das letzte Glied in der Verarbeitungskette eines Stream. Sie liefern keinen weiteren Stream zurück, lassen sich nicht verketten und der Stream ist verbraucht, es lassen sich keine weiteren Operationen mehr ausführen. Sie stoßen die Verarbeitung der intermediären Operationen an. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 16

Filter-Map-Reduce Big-Data erfordert häufig Algorithmen, die aus gefilterten Daten ein Ergebnis berechnen. Der Google filter-map-reduce Ansatz hilft: Stream<String> stream = list.stream(); //.parallel(); // optional Optional<String> result = stream.filter(s -> s.length() > wordlength).map(s -> s.touppercase()).reduce((s1, s2) -> s1 + s2); String msg = result.get(); Die reduce Operation konkateniert die Zeichenketten bis alle gefilterten Zeichen zusammengesetzt sind. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 17

Zusammenfassung Streams operieren effizient auf großen Datenmengen einer zugrunde liegenden Container Klasse. Sie erlauben es beliebige filter oder map Algorithmen zu verschachteln und sowohl seriell oder parallel auszuführen. Algorithmen können seit JDK v1.8 intuitiv als Lambda Ausdrücke bereitgestellt oder aber auch als große selbstgeschriebene Funktionen programmiert werden. Mittels der Stream API bewegt sich Java in Richtung Funktionale Programmierung. Prof. Dr. Nikolaus Wulff Höhere Programmierkonzepte 18