Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke –...

43
Java 8: Lambdas, Streams & Co Mindblast - 10. April 2014 Ruedi Arnold

Transcript of Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke –...

Page 1: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Java 8: Lambdas, Streams & Co

Mindblast - 10. April 2014

Ruedi Arnold

Page 2: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Zusammenfassung [ausgeblendete Folie!]

Zusammenfassung: Am 18. März 2014 wurde Java 8 veröffentlicht und die Sprache damit nach jahrelangen Diskussionen um fundamentale Konzepte erweitert! Vor allem erhält nun Java durch Lambdas neue Sprachmittel, um funktional(er) programmieren zu können. In diesem Vortrag erläutere ich Lambda-Ausdrücke, inklusive funktionale Interfaces und die ebenfalls neuen Methodenreferenzen. Und ich zeige, wie Lambda-Ausdrücke mittels Streams (und fluent programming) auf Collections angewandt werden können. Daneben gehe ich kurz auf weitere wichtige Neuerungen wie default- und statische-Methoden für Interfaces ein.

Mindblast "Java 8: Lambdas, Streams & Co" 2 10. April 2014

Page 3: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Übersicht

§  Lambda-Ausdrücke

–  funktionale Interfaces

–  Methodenreferenzen

§  Streams + Operations

–  intermediate / terminal

–  stateless / stateful

–  short-circuiting

§  Weitere Java 8 Neuigkeiten –  Interfaces: default- und statische Methoden

Mindblast "Java 8: Lambdas, Streams & Co" 3 10. April 2014

Page 4: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

(M)eine Motivation für Lambdas...

§  Bsp.: Event-Listener registrieren...

–  Java < 8 („was wir bisher sagen mussten...“)

Code-Bsp. von http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#lambda-expressions-in-gui-applications

Mindblast "Java 8: Lambdas, Streams & Co" 4

btn.setOnAction(new EventHandler<ActionEvent>() {

@Override public void handle(ActionEvent event) { System.out.println("Hello World!"); }

});

10. April 2014

http

://fa

tmoh

nsco

op.fi

les.w

ordp

ress

.com

/201

0/06

/bla

hbla

h.jp

g

http://1.bp.blogspot.com/-bLPVKKfLakE/T-0JWedUwXI/ AAAAAAAAADI/Clp7TnY048o/s1600/Short-and-to-the-point.jpg

btn.setOnAction( event -> System.out.println("Hello World!“)

);

–  Java 8 („...und was wir eigentlich meinten“ ;-)

Page 5: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Lambda-Ausdrücke (Kurz: „Lambdas“)

§  Lambdas stammen von funktionalen Sprachen

–  Anonyme Methode •  „ad-hoc“ Implementierung von Funktionalität

–  „Code as Data“ •  Funktionalität als Parameter/Rückgabewert herumreichen

–  Überlegen gegenüber (anonymen) inneren Klassen

•  Prägnante Syntax, weniger Code, lesbarer...

...“funktionaler“! J

Mindblast "Java 8: Lambdas, Streams & Co" 5 10. April 2014

Page 6: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Lambda-Ausdrücke: Formale Beschreibung

Mindblast "Java 8: Lambdas, Streams & Co" 6

lambda = ArgList "->" Body

ArgList = Identifier

| "(" Identifier [ "," Identifier ]* ")"

| "(" Type Identifier [ "," Type Identifier ]* ")“

Body = Expression

| "{" [ Statement ";" ]+ "}"

10. April 2014

§  Bemerkungen –  Rückgabetyp wird nie angegeben, sondern immer abgeleitet

–  Argumenttypen können weggelassen werden, dann wird Typ abgeleitet

Page 7: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Lambda-Ausdrücke: Beispiele I

Mindblast "Java 8: Lambdas, Streams & Co" 7

(int x, int y) -> { return x+y; }

// Argument type is inferred: (x, y) -> { return x+y; }

// No brackets needed if only one argument x -> { return x+1; }

// No arguments needed () -> { System.out.println(“I am a Runnable”); }

10. April 2014

Page 8: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Lambda-Ausdrücke: Beispiele II

Mindblast "Java 8: Lambdas, Streams & Co" 8

// Lambda using a statement block a -> {

if (a.balance() < limit) a.alert();

else a.okay(); }

// Single expression a -> (a.balance() < limit) ? a.alert() : a.okay()

// returns Account (Account a) -> { return a; }

// returns int () -> 5;

10. April 2014

Page 9: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Typ von Lambda-Ausdrücken?

Mindblast "Java 8: Lambdas, Streams & Co" 9

???WhatLambdaType??? myLambda = (Account a) -> {if (a.balance() < limit) a.alert();

};

10. April 2014

§  Neuer Begriff: functional Interface –  Functional Interface ≈ „Interface mit einer abstrakten Methode“

•  Gibt (optional) Annotation @FunctionalInterface

§  D.h. wir bleiben in bekannter Java-Welt! –  Lambda = „Interface-Instanz“

–  Alternative Interpretation: Neue „->“-Syntax ist „nur“ syntactic sugar...

Page 10: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Typ von Lambdas = functional interface

Mindblast "Java 8: Lambdas, Streams & Co" 10

@FunctionalInterface interface Consumer<T> {public void accept(T a);}

Consumer<Account> myLambda = (Account a) -> {if (a.balance() < limit) a.alert();

};

10. April 2014

Lambdas werden in Instanzen von functional Interface umgewandelt

§  Functional Interface ≈ Interface mit einer abstrakten Methode

§  Parametertyp(en), Return-Typ, Checked Exceptions müssen passen

§  Name vom functional Interface und dessen Methodenname sind irrelevant

§  Umwandlung benötigt Type-Ableitung (type inference)! –  Lambdas nur möglich, wenn Ziel-Typ vom Kontext abgeleitet werden kann

•  Ableitung durch Zuweisung, Methodenaufruf, Return-Anweisung, Casts, ...

Page 11: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Package java.util.function

§  Vorgegebene Sammlung von „functional interfaces“

§  Verschieden Typen (Namenskonvention) –  Consumer: Kein Resultat

–  Function: Produziert Resultat

–  Operator: Produziert Resultat vom Argument-Typ

–  Supplier: Produziert Resultat ohne Argument

–  Predicate: Produziert boolean-Resultat

Mindblast "Java 8: Lambdas, Streams & Co" 11 10. April 2014

Page 12: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Package java.util.function

§  Vorgegebene Sammlung von functional interfaces

§  Verschieden Typen (Naming) –  Consumer: Kein Resultat

–  Function: Produziert Resultat

–  Operator: Produziert Resultat vom Argument-Typ

–  Supplier: Produziert Resultat ohne Argument

–  Predicate: Produziert boolean-Resultat

Mindblast "Java 8: Lambdas, Streams & Co" 12 10. April 2014

Page 13: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Demo 1: erste eigene Lambdas...

Mindblast "Java 8: Lambdas, Streams & Co" 13 10. April 2014

Page 14: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Lambdas are capturing (effectively final)

Mindblast "Java 8: Lambdas, Streams & Co" 14

int x = 5; return y -> {x = 6; return x + y;}; // does not work!

10. April 2014

§  Kompilierfehler: „local variables referenced from a lambda expression must be final or effectively final“

§  Lambdas haben Zugriff auf lokale Variablen vom umschliessenden Scope

–  „lexical scoping“ (Lambdas führen keinen neuen Scope ein)

–  Variablen müssen „effectively final“ sein •  Wie bei Zugriff aus lokalen oder anonyme Klassen

int x = 5; return y -> {return x + y;}; // ok

Page 15: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Methoden-Referenzen, z.B.: String::length

§  Idee: existierende Methode (einer Klasse) als Lambda-Ausdruck verwenden können –  d.h. existierende Methode wird zur Implementation eines functional

Interface

§  Brauchen Kontext, damit korrekter Ziel-Typ abgeleitet werden kann

§  Vorteile gegebenüber Lambdas –  Weniger Code, verständlicher

–  Bestehender Code kann wiederverwendet werden

Mindblast "Java 8: Lambdas, Streams & Co" 15 10. April 2014

Page 16: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Vier Typen von Methoden-Referenzen

§  Statische Methode: ClassName::methodName –  z.B.:

§  Instanzmethode eines Objektes: Expr::methodName –  z.B.:

§  Instanzmethode einer bel. Instanz einer gewissen Klasse: ClassName::methodName

–  z.B.:

§  Konstruktor: ClassName::new

–  z.B.:

Mindblast "Java 8: Lambdas, Streams & Co" 16

System::currentTimeMillis

10. April 2014

System.out::println

String::length

String::new

Page 17: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Mindblast "Java 8: Lambdas, Streams & Co" 17 10. April 2014 h"

p://en

.wikiped

ia.org/w

iki/F

ile:Som

ethingdiffe

rent.jp

g  

Page 18: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Aggregate Operations (aka. Bulk Operations)

§  Idee: Operationen (Funktionen) elegant auf Datenstrukturen anwenden können.

–  Funktionale Sicht: Sequenzen + Operationen

–  OO-Sicht: Collections + interne Iteration

§  Kurz: for-each/filter/map/reduce/usw... für Java J

Mindblast "Java 8: Lambdas, Streams & Co" 18 10. April 2014

Page 19: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Auswahl-Ops.: for-each, filter, map, reduce

§  for-each: Funktionalität auf jedes Element anwenden

Mindblast "Java 8: Lambdas, Streams & Co" 19

accounts.forEach(a -> a.addInterest());

10. April 2014

§  filter: Neue Sequenz erstellen aus den Resultaten, wenn auf jedes originale Element ein Filter angewandt wurde

accounts.filter(a -> a.balance() > 1_000_000 );

§  map: Neue Sequenz erstellen aus den Resultaten, wenn auf jedes originale Element eine Abbildung angewandt wurde.

accounts.map(a -> a.balance());

§  reduce: Produziert einzelnes Resultat aus allen Elementen accounts.map(a -> a.balance()) .reduce(0, (b1, b2) -> b1+b2);

Page 20: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Neue Datenstruktur: Streams

§  „A sequence of elements supporting sequential and parallel aggregate operations.“ (1. Satz API-Doku) –  Streams unterstützen forEach, filter, map, reduce, findAny, skip, peek, ...

–  Haben nichts mit java.io.InputStream, resp. java.io.OutputStream zu tun!

§  „Most streams are backed by collections, arrays, or generating functions“

Mindblast "Java 8: Lambdas, Streams & Co" 20

interface java.util.stream.Stream<T>

10. April 2014

Streams = DIE neue Datenstruktur in Java 8 für „funktionales Bearbeiten und Behandeln“ von Sequenzen!

Page 21: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Primitive Streams §  Streams für Elemente von diesen drei primitiven Datentypen:

–  IntStream –  DoubleStream –  LongStream

§  Achtung: diese „primitive“ Versionen erben nicht von Stream

§  Motivation für primitive Streams: Performanz

§  Keine Streams für char und float

–  Nächst „grösseren“ primitiven Stream-Typ verwenden •  IntStream für char

•  DoubleStream für float

Mindblast "Java 8: Lambdas, Streams & Co" 21 10. April 2014

Page 22: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Woher bekommen wir Streams?

§  Zwei neue Methoden in Collection<T>

§  Aus einem java.util.Array mittels

–  Inkl. überladene Versionen (primitive Typen, Ranges, ...)

§  Aus statischen Stream-Factories (Stream-Interfaces)

§  ... Mindblast "Java 8: Lambdas, Streams & Co" 22

Stream<E> stream() // sequential functionality

Stream<E> parallelStream() // parallel functionality

10. April 2014

static <T> Stream<T> stream(T[] array)

static <T> Stream<T> of(T... values) static IntStream range(int startInc, int endExc)

Page 23: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

intermediate / terminal Operations

Es gibt Stream-Operationen, welche...

§  wieder einen Stream produzieren: filter(), map(), ... –  intermediate (lazy)

§  etwas anderes tun: forEach(), reduce(),... –  terminal (eager)

Mindblast "Java 8: Lambdas, Streams & Co" 23

double sum = accountCol.stream() .mapToDouble(a -> a.balance()) .reduce(0, (b1, b2) -> b1+b2);

10. April 2014

Page 24: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Stream-Auswertung bei terminal-Operation §  intermediate-Streams werden nicht direkt ausgewertet

–  sondern erst wenn eine terminal-Operation aufgerufen wird

Mindblast "Java 8: Lambdas, Streams & Co" 24

String[] txt = { "This", "is", "a", "stream", "demo"}; Arrays.stream(txt).filter(s -> s.length() > 3) .mapToInt(s -> s.length()) .reduce(0, (l1, l2) -> l1 + l2);

10. April 2014

"This" "is" "a" "stream" "demo"

"This" "stream" "demo"

4 6 4

0 4 10 14

filter

mapToInt

reduce

Code sieht so aus (eine Operation nach der andern)

wirklich ausgeführt (in einem Durchgang!)

Page 25: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Stream-Auswertung bei terminal-Operation §  intermediate-Streams werden nicht direkt ausgewertet

–  sondern erst wenn eine terminal-Operation aufgerufen wird

Mindblast "Java 8: Lambdas, Streams & Co" 25

String[] txt = { "This", "is", "a", "stream", "demo"}; Arrays.stream(txt).filter(s -> s.length() > 3) .mapToInt(s -> s.length()) .reduce(0, (l1, l2) -> l1 + l2);

10. April 2014

"This" "is" "a" "stream" "demo"

"This" "stream" "demo"

4 6 4

0 4 10 14

filter

mapToInt

reduce

Code sieht so aus (eine Operation nach der andern)

wirklich ausgeführt (in einem Durchgang!)

Page 26: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

terminal operations = consuming operations

§  Regel: auf Streams nur eine „terminal operation“ aufrufen! –  Empfehlung: fluent programming...

Mindblast "Java 8: Lambdas, Streams & Co" 26 10. April 2014

IntStream is = IntStream.range(0, 7) .filter(i -> i >= 3); is.forEach(i -> System.out.print(i + ", ")); // 1. consumer ok System.out.println(); int sum = is.sum(); // 2. consumer: problem!

Page 27: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Streams: fluent programming

§  „fluent programming“ bedeutet hier –  Stream konstruieren

–  intermediate operations anwenden (liefern jeweils neue Streams)

–  beenden mit einer „terminal stream operation“

§  Beispiel-Code aus der API-Doku:

Quizfrage: Wo ist sum() definiert? (Hinweis: nicht in Stream...)

Mindblast "Java 8: Lambdas, Streams & Co" 27 10. April 2014

int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight()) .sum();

Page 28: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Demo 2: Stream Operations

Mindblast "Java 8: Lambdas, Streams & Co" 28 10. April 2014

Page 29: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

stateless intermediate operations

§  Beispiele: filter(), map(), ...

§  Operation hängt nur vom aktuellen Stream-Element ab... –  z.B.: filter()-Prädikat angewandt auf jedes Element evaluiert zu

•  true: Element geht in den Rückgabe-Stream

•  false: Element wird fallen gelassen (und geht nicht in den Rückgabe-Stream)

§  Fazit: Einfach handhabbar! J

Mindblast "Java 8: Lambdas, Streams & Co" 29 10. April 2014

Page 30: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

stateful intermediate operations

§  Beispiele: limit(), substream(), distinct(), sorted(), ...

§  Operation braucht zusätzlichen Zustand und aktuelles Stream-Element um zu entscheiden was zu tun... –  z.B.: distinct(): Element geht in den Rückgabe-Stream, falls es bisher noch

nicht aufgetaucht ist (gemäss equals())

§  Fazit: Nicht so einfach handhabbar! L –  z.B. bei Parallelisierung...

Mindblast "Java 8: Lambdas, Streams & Co" 30 10. April 2014

Page 31: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

stateful operation: sorted()...

§  ist die komplexeste und restriktivste „stateful operation“!

§  Stream wird zwischengespeichert & mehrmals durchlaufen!

–  d.h. sorted-Operation wird anders ausgeführt als andere Ops.

–  Schlechteste Performanz!

Mindblast "Java 8: Lambdas, Streams & Co" 31 10. April 2014

... .stream

.statelessOps()

.sorted()

.statelessOps()

.terminal();

Page 32: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

short-circuiting operations...

§  ...können Abarbeitung stoppen, vor das letzte Element erreicht ist

§  intermediate

–  limit(long maxSize)

–  skip(long n)

§  terminal –  anyMatch(...) / noneMatch(...) / allMatch(...)

–  findAny(...) / findFirst(...)

Mindblast "Java 8: Lambdas, Streams & Co" 32 10. April 2014

Page 33: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Sequentielle / parallele Streams

§  Gewisse Operationen unterscheiden zwischen parallelen und sequentiellen Streams

§  z.B. in der Doku von forEach(): „The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does not guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of parallelism. For any given element, the action may be performed at whatever time and in whatever thread the library chooses. If the action accesses shared state, it is responsible for providing the required synchronization.“

§  D.h. wir müssen dies ggf. berücksichtigen!

Mindblast "Java 8: Lambdas, Streams & Co" 33 10. April 2014

Page 34: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Stream-Operationen: Lambda-Parameter

Anforderungen an Lambdas (der meisten Stream-Ops) §  zustandslos (Empfehlung, „good practise“: keine Seiteneffekte)

§  non-interfering = Keine Änderung an Stream-Datenquelle –  D.h. keine Änderung durch anderen Thread oder durch Seiteneffekt vom Lambda

–  Hinweis: „non-inference“ betrifft die Datenquelle vom Stream und nicht die Elemente der Datenquelle (diese dürfen verändert werden)

Mindblast "Java 8: Lambdas, Streams & Co" 34 10. April 2014

List<Integer> ints = new ArrayList<>(); ... ints.stream().map(i -> 2*i) .forEach(j -> ints.add(j)); // No!

List<Account> accountCol = ... ; accountCol.forEach(a -> a.addInterest()); // Ok.

Page 35: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Ausnahme von der Regel: Lambdas forEach()

§  Lambdas für forEach() dürfen Zustand haben und Seiteneffekte produzieren

§  void forEach(Consumer<? super T> action) –  Doku-Auszug: „If the action accesses shared state, it is

responsible for providing the required synchronization.“

Mindblast "Java 8: Lambdas, Streams & Co" 35 10. April 2014

Page 36: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

...unendliche Streams?

§  Beispiel für Marc

§  static DoubleStream generate(DoubleSupplier s) –  „Returns an infinite sequential unordered stream where each

element is generated by the provided DoubleSupplier. This is suitable for generating constant streams, streams of random elements, etc. “

–  Ähnlich: iterate(...) für „infinite sequential ordered Streams“

Mindblast "Java 8: Lambdas, Streams & Co" 36 10. April 2014

long sampleSize = 1_000L; double sum = DoubleStream.generate(Math::random) .skip(7_000_000L) .limit(sampleSize) .sum(); System.out.println("average = " + (sum / sampleSize));

Page 37: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Mindblast "Java 8: Lambdas, Streams & Co" 37 10. April 2014 h"

p://en

.wikiped

ia.org/w

iki/F

ile:Som

ethingdiffe

rent.jp

g  

Page 38: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Weitere Java 8 Neuigkeiten

§  Interfaces

–  default- und statische Methoden

§  Neues Date-Time Package

–  Brauchbar, ähnlich wie „Joda Time“ (http://www.joda.org/joda-time/)

§  Nashorn JavaScript-Engine als Teil vom JDK (!)

§  Diverse JavaFX-Neugikeiten...

§  Diverse Security-Neuigkeiten

§  u.v.a.m.

§  ... Mindblast "Java 8: Lambdas, Streams & Co" 38 10. April 2014

Page 39: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Interfaces: default- und statische Methoden

§  Beispiel-Interface (Syntax)

§  Semantik „wie erwartet“:

Mindblast "Java 8: Lambdas, Streams & Co" 39 10. April 2014

public interface DemoInterface {

default int getLuckyNumber() { return 7; }

static int getEight() { return 8; }

}

int eight = DemoInterface.getEight();

DemoInterface di = new DemoInterface() {};

int seven = di.getLuckyNumber();

Page 40: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Problem bei Mehrfachvererbung?

§  2 Interfaces mit gleicher default-Methode

–  Compilierfehler: InterfaceDemo inherits unrelated defaults for

getLuckyNumber() from types DemoInterface and OtherInterface

§  Lösung: Methode muss überschrieben werden

Mindblast "Java 8: Lambdas, Streams & Co" 40 10. April 2014

public interface DemoInterface { default int getLuckyNumber() { return 7; } } public interface OtherInterface { default int getLuckyNumber() { return 8; } } public class InterfaceDemo implements DemoInterface, OtherInterface { }

public class InterfaceDemo implements DemoInterface, OtherInterface {

@Override public int getLuckyNumber() { return DemoInterface.super.getLuckyNumber(); } // ...noted new super syntax?

}

Page 41: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Anwendung von default-Methoden

§  Interface Collection<E>

§  d.h. bestehende Interfaces können erweitert werden! ...und so hat plötzlich jede Collection-Implementierung eine stream()-Methode oder Comparator<T>.naturalOrder() liefert immer einen Comparator. J

Mindblast "Java 8: Lambdas, Streams & Co" 41 10. April 2014

Page 42: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Ende & Fazit „Java 8: Lambdas, Streams & Co“

§  Viele (Sprach-)Neuigkeiten

§  „Java goes functional“!

–  streams & lambdas

§  Auflösung Titelfolie, Resultat von diesem Ausdruck

–  Wert: “Hansjörg, Roger“

–  Typ: Optional<String>

...es gibt also noch viel mehr zu entdecken! J

Mindblast "Java 8: Lambdas, Streams & Co" 42 10. April 2014

Optional<String> allNames = Arrays.asList("Hansjörg", "Marc", "Roger") .stream() .filter(name -> name.length() > 4) .reduce((a, b) -> a+", "+b); if (allNames.isPresent()) { String result = allNames.get(); }

Page 43: Java 8: Lambdas, Streams & Co - Ruedi Arnold · 2014-04-14 · Übersicht ! Lambda-Ausdrücke – funktionale Interfaces – Methodenreferenzen ! Streams + Operations – intermediate

Quellen & Referenzen

§  Oracle / Java 8 –  API-Doku: http://docs.oracle.com/javase/8/docs/api/

–  release notes: http://www.oracle.com/technetwork/java/javase/8train-relnotes-latest-2153846.html

–  „what‘s new in jdk 8“: http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html

–  Java Tutorials: http://docs.oracle.com/javase/tutorial/java/index.html

§  Lambda Tutorial & Reference von Angelika Langer / Klaus Kreft –  http://www.angelikalanger.com/Lambdas/TOC.html

–  Hack-Session zu Lambdas & Streams in Java bei JUG.CH (17.12.2013)

§  Blogpost „Everything about Java 8“ –  http://www.techempower.com/blog/2013/03/26/everything-about-java-8/

Mindblast "Java 8: Lambdas, Streams & Co" 43 10. April 2014