Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Lambdas 
& 
Streams 
In 
JDK8 
Making 
Bulk 
Opera/ons 
Simple 
Simon 
Ri6er 
Head 
of 
Java 
Technology 
Evangelism 
Orac...
Safe 
Harbor 
Statement 
The 
following 
is 
intended 
to 
outline 
our 
general 
product 
direcTon. 
It 
is 
intended 
fo...
java.util.concurrent 
(jsr166) 
1.0 5.0 6 7 8 
1996 … 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 
Copyrig...
Lambdas 
In 
Java 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved.
The 
Problem: 
External 
IteraTon 
List<Student> 
students 
= 
... 
double 
highestScore 
= 
0.0; 
for 
(Student 
s 
: 
st...
Internal 
IteraTon 
With 
Inner 
Classes 
• IteraTon 
handled 
by 
the 
library 
• Not 
inherently 
serial 
– 
traversal 
...
Internal 
IteraTon 
With 
Lambdas 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
List<Stu...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Lambda 
Expressions 
Some 
Details 
• Lambd...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Lambda 
Expression 
Types 
• Single-­‐metho...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Local 
Variable 
Capture 
• Lambda 
express...
What 
Does 
‘this’ 
Mean 
For 
Lambdas? 
• ‘this’ 
refers 
to 
the 
enclosing 
object, 
not 
the 
lambda 
itself 
Copyrigh...
Referencing 
Instance 
Variables 
Which 
are 
not 
final, 
or 
effecTvely 
final 
Copyright 
© 
2014, 
Oracle 
and/or 
its...
Referencing 
Instance 
Variables 
The 
compiler 
helps 
us 
out 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
Al...
static 
T 
void 
sort(List<T> 
l, 
Comparator<? 
super 
T> 
c); 
List<String> 
list 
= 
getList(); 
Collections.sort(list,...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Method 
References 
• Method 
references 
l...
Factory<List<String>> 
f 
= 
() 
-­‐> 
return 
new 
ArrayList<String>(); 
Replace 
with 
Copyright 
© 
2014, 
Oracle 
and/...
Library 
EvoluTon 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved.
int 
heaviestBlueBlock 
= 
blocks 
.filter(b 
-­‐> 
b.getColor() 
== 
BLUE) 
.map(Block::getWeight) 
.reduce(0, 
Integer::...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
SoluTon: 
Default 
Methods 
• Specified 
in...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Virtual 
Extension 
Methods 
Stop 
right 
t...
FuncTonal 
Interface 
DefiniTon 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
• Single 
...
Lambdas 
In 
Full 
Flow: 
Streams 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved.
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Aggregate 
OperaTons 
• Most 
business 
log...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Stream 
Overview 
At 
The 
High 
Level 
• A...
Source 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Stream 
Overview 
• A 
stream 
pipe...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Stream 
Sources 
Many 
Ways 
To 
Create 
• ...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Stream 
Sources 
Provide 
• Access 
to 
str...
Stream 
Terminal 
OperaTons 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
• The 
pipelin...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Maps 
and 
FlatMaps 
Map 
Values 
in 
a 
St...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Optional<T> 
Reducing 
NullPointerException...
NullPointerException 
Occurrences 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Optional...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Example 
1 
Convert 
words 
in 
list 
to 
u...
Example 
1 
Convert 
words 
in 
list 
to 
upper 
case 
(in 
parallel) 
List<String> 
output 
= 
wordList 
.parallelStream(...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Example 
2 
• BufferedReader 
has 
new 
met...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Example 
3 
Join 
lines 
3-­‐4 
into 
a 
si...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Example 
4 
Collect 
all 
words 
in 
a 
fil...
Example 
5 
List 
of 
unique 
words 
in 
lowercase, 
sorted 
by 
length 
List<String> 
output 
= 
reader 
.lines() 
.flatM...
Example 
6: 
Real 
World 
Infinite 
stream 
from 
thermal 
sensor 
private 
int 
double 
currentTemperature; 
... 
thermal...
Example 
6: 
Real 
World 
Infinite 
stream 
from 
thermal 
sensor 
private 
int 
double 
currentTemperature; 
... 
thermal...
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights 
reserved. 
Conclusions 
• Java 
needs 
lambda 
stateme...
Simon 
Ri6er 
Oracle 
CorporarTon 
Twi6er: 
@speakjava 
Copyright 
© 
2014, 
Oracle 
and/or 
its 
affiliates. 
All 
rights...
Lambdas And Streams in JDK8
Upcoming SlideShare
Loading in …5
×

Lambdas And Streams in JDK8

708 views

Published on

Latest version of my Lambdas and Streams in JDK8 presentation used at JAX London, 14 Oct 2014

Published in: Software
  • Be the first to comment

Lambdas And Streams in JDK8

  1. 1. Lambdas & Streams In JDK8 Making Bulk Opera/ons Simple Simon Ri6er Head of Java Technology Evangelism Oracle Corp. Twi6er: @speakjava Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  2. 2. Safe Harbor Statement The following is intended to outline our general product direcTon. It is intended for informaTon purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or funcTonality, and should not be relied upon in making purchasing decisions. The development, release, and Tming of any features or funcTonality described for Oracle’s products remains at the sole discreTon of Oracle. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 3
  3. 3. java.util.concurrent (jsr166) 1.0 5.0 6 7 8 1996 … 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. java.lang.Thread Fork/Join Framework (jsr166y) Concurrency in Java Project Lambda Phasers, etc (jsr166)
  4. 4. Lambdas In Java Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  5. 5. The Problem: External IteraTon List<Student> students = ... double highestScore = 0.0; for (Student s : students) { if (s.getGradYear() == 2011) { if (s.getScore() > highestScore) highestScore = s.score; } } • Our code controls iteraTon • Inherently Copyright © 2014, Oracle and/or its affiliates. All rights reserved. serial: iterate from beginning to end • Not thread-­‐safe • Business logic is stateful • Mutable accumulator variable
  6. 6. Internal IteraTon With Inner Classes • IteraTon handled by the library • Not inherently serial – traversal Copyright © 2014, Oracle and/or its affiliates. All rights reserved. may be done in parallel • Traversal may be done lazily – so one pass, rather than three • Thread safe – client logic is stateless • High barrier to use – SyntacTcally ugly More FuncTonal double highestScore = students .filter(new Predicate<Student>() { public boolean op(Student s) { return s.getGradYear() == 2011; } }) .map(new Mapper<Student,Double>() { public Double extract(Student s) { return s.getScore(); } }) .max();
  7. 7. Internal IteraTon With Lambdas Copyright © 2014, Oracle and/or its affiliates. All rights reserved. List<Student> students = ... double highestScore = students .filter(Student s -­‐> s.getGradYear() == 2011) .map(Student s -­‐> s.getScore()) .max(); • More readable • More abstract • Less error-­‐prone NOTE: This is not JDK8 code
  8. 8. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Lambda Expressions Some Details • Lambda expressions represent anonymous funcTons – Same structure as a method • typed argument list, return type, set of thrown excepTons, and a body – Not associated with a class • We now have parameterised behaviour, not just values double highestScore = students. filter(Student s -­‐> s.getGradYear() == 2011). map(Student s -­‐> s.getScore()) max(); What How
  9. 9. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Lambda Expression Types • Single-­‐method interfaces are used extensively in Java – DefiniTon: a func2onal interface is an interface with one abstract method – Func2onal interfaces are idenTfied structurally – The type of a lambda expression will be a func2onal interface • Lambda expressions provide implementaTons of the abstract method interface Comparator<T> { boolean compare(T x, T y); } interface FileFilter { boolean accept(File x); } interface Runnable { void run(); } interface ActionListener { void actionPerformed(…); } interface Callable<T> { T call(); }
  10. 10. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Local Variable Capture • Lambda expressions can refer to effec2vely final local variables from the enclosing scope • EffecTvely final: A variable that meets the requirements for final variables (i.e., assigned once), even if not explicitly declared final • Closures on values, not variables void expire(File root, long before) { root.listFiles(File p -­‐> p.lastModified() <= before); }
  11. 11. What Does ‘this’ Mean For Lambdas? • ‘this’ refers to the enclosing object, not the lambda itself Copyright © 2014, Oracle and/or its affiliates. All rights reserved. • Think of ‘this’ as a final predefined local • Remember the Lambda is an anonymous func2on – It is not associated with a class – Therefore there can be no ‘this’ for the Lambda
  12. 12. Referencing Instance Variables Which are not final, or effecTvely final Copyright © 2014, Oracle and/or its affiliates. All rights reserved. class DataProcessor { private int currentValue; public void process() { DataSet myData = myFactory.getDataSet(); dataSet.forEach(d -­‐> d.use(currentValue++)); } }
  13. 13. Referencing Instance Variables The compiler helps us out Copyright © 2014, Oracle and/or its affiliates. All rights reserved. class DataProcessor { private int currentValue; public void process() { DataSet myData = myFactory.getDataSet(); dataSet.forEach(d -­‐> d.use(this.currentValue++); } } ‘this’ (which is effecTvely final) inserted by the compiler
  14. 14. static T void sort(List<T> l, Comparator<? super T> c); List<String> list = getList(); Collections.sort(list, (String x, String y) -­‐> x.length() -­‐ y.length()); Collections.sort(list, (x, y) -­‐> x.length() -­‐ y.length()); Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Type Inference • The compiler can oien infer parameter types in a lambda expression § Inferrence based on the target funcTonal interface’s method signature • Fully staTcally typed (no dynamic typing sneaking in) – More typing with less typing
  15. 15. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Method References • Method references let us reuse a method as a lambda expression FileFilter x = File f -­‐> f.canRead(); FileFilter x = File::canRead;
  16. 16. Factory<List<String>> f = () -­‐> return new ArrayList<String>(); Replace with Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Constructor References • Same concept as a method reference – For the constructor Factory<List<String>> f = ArrayList<String>::new;
  17. 17. Library EvoluTon Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  18. 18. int heaviestBlueBlock = blocks .filter(b -­‐> b.getColor() == BLUE) .map(Block::getWeight) .reduce(0, Integer::max); Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Library EvoluTon Goal • Requirement: aggregate operaTons on collecTons – New methods required on CollecTons to facilitate this • This is problemaTc – Can’t add new methods to interfaces without modifying all implementaTons – Can’t necessarily find or control all implementaTons
  19. 19. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. SoluTon: Default Methods • Specified in the interface • From the caller’s perspecTve, just an ordinary interface method • Provides a default implementaTon • Default only used when implementaTon classes do not provide a body for the extension method • ImplementaTon classes can provide a be6er version, or not interface Collection<E> { default Stream<E> stream() { return StreamSupport.stream(spliterator()); } }
  20. 20. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Virtual Extension Methods Stop right there! • Err, isn’t this implemenTng mulTple inheritance for Java? • Yes, but Java already has mulTple inheritance of types • This adds mulTple inheritance of behavior too • But not state, which is where most of the trouble is • Can sTll be a source of complexity • Class implements two interfaces, both of which have default methods • Same signature • How does the compiler differenTate? • StaTc methods also allowed in interfaces in Java SE 8
  21. 21. FuncTonal Interface DefiniTon Copyright © 2014, Oracle and/or its affiliates. All rights reserved. • Single Abstract Method (SAM) type • A funcTonal interface is an interface that has one abstract method – Represents a single funcTon contract – Doesn’t mean it only has one method • @FunctionalInterface annotaTon – Helps ensure the funcTonal interface contract is honoured – Compiler error if not a SAM
  22. 22. Lambdas In Full Flow: Streams Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  23. 23. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Aggregate OperaTons • Most business logic is about aggregate operaTons – “Most profitable product by region” – “Group transacTons by currency” • As we have seen, up to now, Java uses external iteraTon – Inherently serial – FrustraTngly imperaTve • Java SE 8’s answer: The Stream API – With help from Lambdas
  24. 24. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Stream Overview At The High Level • AbstracTon for specifying aggregate computaTons – Not a data structure – Can be infinite • Simplifies the descripTon of aggregate computaTons – Exposes opportuniTes for opTmisaTon – Fusing, laziness and parallelism
  25. 25. Source Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Stream Overview • A stream pipeline consists of three types of things – A source – Zero or more intermediate operaTons – A terminal operaTon • Producing a result or a side-­‐effect Pipeline int total = transactions.stream() .filter(t -­‐> t.getBuyer().getCity().equals(“London”)) .mapToInt(Transaction::getPrice) .sum(); Intermediate operaTon Terminal operaTon
  26. 26. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Stream Sources Many Ways To Create • From collecTons and arrays – Collection.stream() – Collection.parallelStream() – Arrays.stream(T array) or Stream.of() • StaTc factories – IntStream.range() – Files.walk() • Roll your own – java.util.Spliterator
  27. 27. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Stream Sources Provide • Access to stream elements • DecomposiTon (for parallel operaTons) – Fork-­‐join framework • Stream characterisTcs – ORDERED – SORTED – DISTINCT – SIZED – NONNULL – IMMUTABLE – CONCURRENT
  28. 28. Stream Terminal OperaTons Copyright © 2014, Oracle and/or its affiliates. All rights reserved. • The pipeline is only evaluated when the terminal operaTon is called – All operaTons can execute sequenTally or in parallel – Intermediate operaTons can be merged • Avoiding mulTple redundant passes on data • Short-­‐circuit operaTons (e.g. findFirst) • Lazy evaluaTon – Stream characterisTcs help idenTfy opTmisaTons • DISTINT stream passed to distinct() is a no-­‐op
  29. 29. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Maps and FlatMaps Map Values in a Stream Map FlatMap Input Stream Input Stream 1-­‐to-­‐1 mapping 1-­‐to-­‐many mapping Output Stream Output Stream
  30. 30. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Optional<T> Reducing NullPointerException Occurrences String direction = gpsData.getPosition().getLatitude().getDirection(); String direction = “UNKNOWN”; if (gpsData != null) { Position p = gpsData.getPosition(); if (p != null) { Latitude latitude = p.getLatitude(); if (latitude != null) direction = latitude.getDirection(); } }
  31. 31. NullPointerException Occurrences Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Optional<T> Reducing • Indicates that reference may, or may not have a value – Makes developer responsible for checking – A bit like a stream that can only have zero or one elements Optional<GPSData> maybeGPS = Optional.ofNullable(gpsData); maybeGPS.ifPresent(GPSData::printPosition); GPSData gps = maybeGPS.orElse(new GPSData()); maybeGPS.filter(g -­‐> g.lastRead() < 2).ifPresent(GPSData.display());
  32. 32. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Example 1 Convert words in list to upper case List<String> output = wordList .stream() .map(String::toUpperCase) .collect(Collectors.toList());
  33. 33. Example 1 Convert words in list to upper case (in parallel) List<String> output = wordList .parallelStream() .map(String::toUpperCase) .collect(Collectors.toList()); Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  34. 34. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Example 2 • BufferedReader has new method – Stream<String> lines() Count lines in a file long count = bufferedReader .lines() .count();
  35. 35. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Example 3 Join lines 3-­‐4 into a single string String output = bufferedReader .lines() .skip(2) .limit(2) .collect(Collectors.joining());
  36. 36. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Example 4 Collect all words in a file into a list List<String> output = reader .lines() .flatMap(line -­‐> Stream.of(line.split(REGEXP))) .filter(word -­‐> word.length() > 0) .collect(Collectors.toList());
  37. 37. Example 5 List of unique words in lowercase, sorted by length List<String> output = reader .lines() .flatMap(line -­‐> Stream.of(line.split(REGEXP))) .filter(word -­‐> word.length() > 0) .map(String::toLowerCase) .distinct() .sorted((x, y) -­‐> x.length() -­‐ y.length()) .collect(Collectors.toList()); Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  38. 38. Example 6: Real World Infinite stream from thermal sensor private int double currentTemperature; ... thermalReader .lines() .mapToDouble(s -­‐> Double.parseDouble(s.substring(0, s.length() -­‐ 1))) .map(t -­‐> ((t – 32) * 5 / 9) .filter(t -­‐> t != currentTemperature) .peek(t -­‐> listener.ifPresent(l -­‐> l.temperatureChanged(t))) .forEach(t -­‐> currentTemperature = t); Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  39. 39. Example 6: Real World Infinite stream from thermal sensor private int double currentTemperature; ... thermalReader .lines() .mapToDouble(s -­‐> Double.parseDouble(s.substring(0, s.length() -­‐ ))) .map(t -­‐> ((t – 32) * 5 / 9) .filter(t -­‐> t != this.currentTemperature) .peek(t -­‐> listener.ifPresent(l -­‐> l.temperatureChanged(t))) .forEach(t -­‐> this.currentTemperature = t); Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
  40. 40. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Conclusions • Java needs lambda statements – Significant improvements in exisTng libraries are required • Require a mechanism for interface evoluTon – SoluTon: virtual extension methods • Bulk operaTons on CollecTons – Much simpler with Lambdas • Java SE 8 evolves the language, libraries, and VM together
  41. 41. Simon Ri6er Oracle CorporarTon Twi6er: @speakjava Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

×