Java 8 Lambdas und Streams



Ähnliche Dokumente
Java 8 Lambdas und Streams

Java Kurs für Anfänger Einheit 5 Methoden

Java 8. basierend auf Folien von Florian Erhard

Objektorientierte Programmierung. Kapitel 12: Interfaces

Innere Klassen in Java

Objektorientierte Programmierung

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

Einführung in die Programmierung

Java: Vererbung. Teil 3: super()

Einführung in Java. PING e.v. Weiterbildung Andreas Rossbacher 24. März 2005

Computeranwendung und Programmierung (CuP)

Prof. Dr. Uwe Schmidt. 21. August Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252)

Einführung in die Java- Programmierung

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

SEP 114. Design by Contract

Prinzipien Objektorientierter Programmierung

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

Programmieren Lernen mit BYOB. Gerald Futschek 5. November 2012

Scala kann auch faul sein

Einführung in die Java- Programmierung

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Session Beans & Servlet Integration. Ralf Gitzel ralf_gitzel@hotmail.de

Die Programmiersprache Java. Dr. Wolfgang Süß Thorsten Schlachter

Kapitel 6. Vererbung

3 Objektorientierte Konzepte in Java

Grundlagen von Python

Objektorientierte Programmierung für Anfänger am Beispiel PHP

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

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Funktionale Programmierung in Java

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Java Einführung Collections

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = Euro ergeben.

Java Virtual Machine (JVM) Bytecode

Algorithmen und Datenstrukturen

Client-Server-Beziehungen

Programmierkurs Java

Javakurs zu Informatik I. Henning Heitkötter

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

Programmieren I. Strategie zum Entwurf von Klassen. Beispiele. Design von Klassen. Dr. Klaus Höppner. Beispiel: Bibliothek

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Zählen von Objekten einer bestimmten Klasse

Vorkurs C++ Programmierung

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java

Kapitel 6. Vererbung

II.1.1. Erste Schritte - 1 -

Selbstbestimmtes Lernen. Proinformatik III Objektorientierte Programmierung. Format. Inhalt. Buzzwords

Einführung in die Programmierung

Kapitel 6. Vererbung

Java Einführung Operatoren Kapitel 2 und 3

Klassendefinitionen verstehen

3. Stored Procedures und PL/SQL

Programmieren Tutorium

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Programmieren in Java

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

5. Tutorium zu Programmieren

Fachdidaktik der Informatik Jörg Depner, Kathrin Gaißer

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

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

Operationalisierbare Qualitätskriterien für die Programmierung mit Erfahrungen aus PRÜ1 und PRÜ2

Übungsblatt 3: Algorithmen in Java & Grammatiken

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

Vererbung & Schnittstellen in C#

Beispiel: DB-Mock (1/7)

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

Gliederung Grundlagen Schlüsselworte try-catch Fehlerobjekte Fehlerklassen Schlüsselwort finally Schlüsselwort throws selbst erstellte Exceptions

Java Einführung Abstrakte Klassen und Interfaces

Internet Explorer Version 6

Große Übung Praktische Informatik 1

Workshop 6. Einführung in die objektorientierte Programmierung. Teil: Java mit BlueJ

Klausur zur Einführung in die objektorientierte Programmierung mit Java

Java Einführung Programmcode

Xcode/Cocoa/Objective-C Crashkurs Programmieren unter Mac OS X

Grundlagen. Kapitel 1

OCP Java SE 8. Lambda

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom b

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

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

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

Professionelle Seminare im Bereich MS-Office

5. Abstrakte Klassen

Delegatesund Ereignisse

Installation der SAS Foundation Software auf Windows

Studentische Lösung zum Übungsblatt Nr. 7

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Programmierparadigmen. Programmierparadigmen. Imperatives vs. objektorientiertes Programmieren. Programmierparadigmen. Agenda für heute, 4.

Fachgebiet Informationssysteme Prof. Dr.-Ing. N. Fuhr. Programmierung Prof. Dr.-Ing. Nobert Fuhr. Übungsblatt Nr. 6

CORBA. Systemprogrammierung WS

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

Einführung in Eclipse und Java

MARCANT - File Delivery System

Erwin Grüner

Java Einführung Packages

WhiteStarUML Tutorial

Excel Funktionen durch eigene Funktionen erweitern.

Transkript:

Java 8 Lambdas und Streams E-Voting Group, 24. Juni 2014 Stephan Fischli Dozent BFH, Software-Architekt ISC-EJPD Berner Fachhochschule Haute école spécialisée t bernoise Bern University of Applied Sciences

Inhalt Einführung Lambda-Ausdrücke Collections, Streams und Bulk-Operationen Fazit

Einführung

Geschichte von Java Collections Date/Time Concurrency Utils Web Services Library Language Platform JDBC RMI Reflection Inner Classes Collections Swing Java IDL strictfp JIT Plugin JNDI HotSpot JDPA Logging NIO XML Security assert Java Web Start Generics Annotations Enums... Try-withresources Multicatch... Dynamic Languages Lambdas JDK 1.0 JDK 1.1 J2SE 1.2 J2SE 1.3 J2SE 1.4 J2SE 5.0 Java SE 6 Java SE 7 Java SE 8 1996 1997 1998 2000 2002 2004 2006 2011 2014

Wichtigste Neuerungen Sprache Annotationen auf Java-Typen (JSR 308) Lambda-Ausdrücke (JSR 335) Bibliotheken Date & Time API (JSR 310) Bulk-Operationen für Collections (JSR 335) Plattform Modulsystem (JSR 277) auf Java 9 verschoben Profile als Ersatz Vollständige Liste http://openjdk.java.net/projects/jdk8/features

Quellen Java 8 SE Spezifikation (JSR 337) https://jcp.org/en/jsr/detail?id=337 JDK 8 Download http://www.oracle.com/technetwork/java/javase/downloads/ Java 8 API Dokumentation http://docs.oracle.com/javase/8/docs/api/ Java Tutorial http://docs.oracle.com/javase/tutorial/

Lambda-Ausdrücke

Warum ein neues Sprachkonstrukt? Java ist objektorientiert, also müssen Funktionen als Methoden von Klassen codiert werden: File[] files = directory.listfiles(new FileFilter() { public boolean accept(file file) { return file.length() < 1024; } }); Mit Lambda-Ausdrücken können Funktionen auch ohne Erzeugung einer Klasse oder eines Objekts übergeben werden: File[] files = directory.listfiles( (File file) -> file.length() < 1024 );

Lambda-Ausdrücke Lambda-Ausdrücke sind Ausdrücke der Form argument list -> body Der Body kann sein: ein einfacher Ausdruck, der ausgewertet wird ein Block von Statements, die ausgeführt werden; kann einen Rückgabewert haben Beispiele (int x, int y, int z) -> x + y + z (Account a1, Account a2) -> a1.balance() - a2.balance() (String s) -> { System.out.println(s); } () -> 42

Funktionale Interfaces Lambda-Ausdrücke sind vom Typ eines funktionalen Interface, das ist ein Interface mit genau einer Methode Beispiele: Main directory.listfiles( (File f) -> f.length()<1024 ) File File[] listfiles(filefilter) FileFilter boolean accept(file) interface FileFilter { boolean accept(file file); } interface Comparator<T> { int compare(t o1, T o2); } interface Runnable { void run(); } interface ActionListener { void actionperformed(actionevent e); }

Verwendung funktionaler Interfaces Funktionale Interfaces dienen oft als Parametertypen bei der Implementierung von Verhaltensmustern wie dem Observer-, Strategyoder Visitor-Pattern Beispiel public File[] listfiles(filefilter filter) { ArrayList<File> files = new ArrayList<>(); for (File file : listfiles()) { if (filter.accept(file)) files.add(f); } return files.toarray(new File[files.size()]); }

Verwendung von Lambda-Ausdrücken Lambda-Ausdrücke können überall verwendet werden, wo ein Objekt eines funktionalen Interfaces benötigt wird, insbesondere in Variablendeklarationen Zuweisungen Methodenaufrufen Return-Statements Beispiele FileFilter filter = (File file) -> file.length() < 1024; Collections.sort(accounts, (Account a1, Account a2) -> a1.balance() - a2.balance()); return () -> { System.out.println("Hello world"); };

Zieltyp eines Lambda-Ausdrucks Der Compiler leitet den Typ eines Lambda-Ausdrucks aus dem Verwendungskontext ab (Zieltyp) Ein Lambda-Ausdruck ist kompatibel zu einem funktionalen Interface, wenn die Parameter, Rückgabewerte und Exceptions zu der Methode des Interface passen Da die Parametertypen aus dem Zieltyp bekannt sind, können sie im Lambda-Ausdruck meistens weggelassen werden FileFilter filter = file -> file.length() < 1024; Collections.sort(accounts, (a1, a2) -> a1.balance() - a2.balance());

Scoping und Variablenbindung Lambda-Ausdrücke definieren keinen eigenen Scope, sondern gehören zum Scope des umgebenden Kontexts Die Referenzen this und super sowie Variablennamen werden somit im Kontext interpretiert Lambda-Ausdrücke dürfen lesend auf lokale Variablen des Kontexts zugreifen, sofern diese effektiv final sind Beispiel int count = 100, sum = 0; Runnable r = () -> { for (int n = 1; n <= count; n++) sum += n; }; // Fehler new Thread(r).start();

Methodenreferenzen Methodenreferenzen sind wie Lambda-Ausdrücke, referenzieren aber existierende Klassen-, Objektmethoden oder Konstruktoren Beispiel: class Account { public static int compare(account a1, Account a2) { return a1.balance() - a2.balance(); } public int compareto(account a) { return this.balance() - a.balance(); } } Collections.sort(accounts, Account::compare); Collections.sort(accounts, Account::compareTo);

Collections, Streams und Bulk-Operationen

Externe vs interne Iteration Das bisherige Collection-Framework basiert auf externer Iteration, d.h. Iterationen werden vom Client kontrolliert: for (Account a: accounts) { if (a.balance() < 0) a.alert(); } Bei einer internen Iteration delegiert der Client die Iteration an die Bibliothek: accounts.foreach(a -> { if (a.balance() < 0) a.alert(); }); Vorteile: Iteration und Logik sind getrennt Optimierte Ausführung möglich

Streams Ein Stream repräsentiert eine Folge von Elementen hat Operationen zur Manipulation aller Elemente, diese beruhen auf interner Iteration kann eine unbeschränkte Grösse haben wird konsumiert, d.h. jede Verarbeitung benötigt einen neuen Stream Ein Stream ist ein Objekt vom generischen Typ Stream<T> oder der spezialisierten Typen IntStream, LongStream, DoubleStream

Erzeugen von Streams Streams können erzeugt werden aus Collections und Arrays accounts.stream() Arrays.stream(text.split("\\s+")) I/O-Kanälen new BufferedReader(in).lines() Files.lines(file), Files.list(dir), Files.walk(dir), Files.find(dir, depth, matcher) Generatorfunktionen Stream.generate(Math::random) Stream.iterate(1, x -> x+1) Stream.empty()

Stream-Operationen Stream-Operationen haben funktionale Interfaces als formale Parameter, die das Verhalten definieren sind funktional, d.h. sie verändern die Quelle des Streams nicht können zustandslos oder zustandsbehaftet sein Stream-Operationen werden in Zwischen- und Terminaloperationen unterschieden

Zwischenoperationen Zwischenoperationen transformieren Streams Stream<T> distinct() Stream<T> limit(long maxsize) Stream<T> skip(long n) Stream<T> filter(predicate<t> predicate) Stream<R> map(function<t, R> mapper) Stream<T> sorted(comparator<t> comparator) Zugehörige Interfaces interface Predicate<T> { boolean test(t o); } interface Function<T,R> { R apply(t o); } interface Comparator<T> { int compare(t o1, T o2); }

Terminaloperationen Terminaloperationen erzeugen ein Resultat oder einen Nebeneffekt long count() Optional<T> findany/findfirst() boolean allmatch/anymatch/nonematch(predicate<t> predicate) Optional<T> min/max(comparator<t> comparator) Optional<T> reduce(binaryoperator<t> accumulator) void foreach(consumer<t> action) Zugehörige Interfaces interface Predicate<T> { boolean test(t o); } interface Comparator<T> { int compare(t o1, T o2); } interface BinaryOperator<T> { T operate(t o1, T o2); } interface Consumer<T> { void accept(t o); }

Pipelines Stream-Operationen werden in Pipelines ausgeführt Eine Pipeline besteht aus einer Quelle, welche die Elemente liefert Zwischenoperationen, welche den Stream transformieren einer Terminaloperation, die ein Resultat produziert Beispiel accounts.stream().filter(a -> a.customer().age() > 65).mapToInt(a -> a.balance()).average();

Laziness Stream-Operationen werden wenn möglich lazy ausgeführt Vorteile: Elemente können in einem Durchgang verarbeitet werden, es braucht keine mehrfachen Iterationen und keine Zwischenspeicher Beim Suchen von Elementen kann die Verarbeitung oft vorzeitig abgebrochen werden

Laziness Stream-Operationen werden wenn möglich lazy ausgeführt Vorteile: Elemente können in einem Durchgang verarbeitet werden, es braucht keine mehrfachen Iterationen und keine Zwischenspeicher Beim Suchen von Elementen kann die Verarbeitung oft vorzeitig abgebrochen werden

Parallelisierung Stream-Pipelines können sequentiell oder parallel ausgeführt werden Für eine parallele Ausführung dürfen sich die Operationen nicht gegenseitig beeinflussen (non-interference) Beispiel accounts.parallelstream().filter(a -> a.customer().age() > 65).mapToInt(a -> a.balance()).average();

Funktionale Programmierung

Programmierparadigmen Imperative Programmierung Strukturiert: Verwendung bestimmter Kontrollstrukturen Prozedural: Aufteilung eines Programms in Prozeduren Modular: Logische Einheiten mit Daten und Prozeduren Objektorientiert: Klassen als instanziierbare Module Deklarative Programmierung Funktional: Aufgabe als funktionaler Ausdruck, Interpreter macht Funktionsauswertung Logisch: Aufgabe als logischer Ausdruck, Interpreter versucht Aussage herzuleiten

Imperative vs funktionale Programmierung Imperative Programme bestehen aus Anweisungen und arbeiten mit Speicherplätzen beschreiben, wie etwas gemacht wird Funktionale Programme bestehen aus Funktionen und arbeiten mit Variablen beschreiben, was gemacht wird Vorteile Funktionen haben keine Nebeneffekte Funktionen werden immer lazy ausgewertet Funktionen höherer Ordnung sind möglich

Fazit

Fazit Lambda-Ausdrücke bieten eine einfache Syntax für anonyme Methoden und fördern dadurch einen neuen Programmierstil (funktionale Programmierung) ermöglichen die Implementierung effizienter Bibliotheken und damit die bessere Nutzung moderner Rechnerarchitekturen

Referenzen Brian Goetz, State of the Lambda http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html http://cr.openjdk.java.net/~briangoetz/lambda/lambda-libraries-final.html http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html Angelika Langer, Lambda Expressions and Streams in Java http://www.angelikalanger.com/lambdas/lambdas.html The Java Tutorial, Lambda Expressions http://docs.oracle.com/javase/tutorial/java/javaoo/lambdaexpressions.html Mark Reinholds, Closures for Java https://blogs.oracle.com/mr/entry/closures

Carl Friedrich Gauss 1+2+3+4+5+...+99+100 =? (1+100)+(2+99)+(3+98)+...+(50+51) = 5050 IntStream.iterate(1, x -> x+1).limit(100).sum()

Danke für Ihre Aufmerksamkeit.