Post on 03-Jun-2018
8/12/2019 Lamda Expressions Tutorial
1/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.1
Virtual developer Day Java2014
Lambda Expressions TutorialSimon Ritter
Head of Java Technology Evangelism
Twitter: @speakjava
8/12/2019 Lamda Expressions Tutorial
2/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.2
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2
1.4 5.0 6 7
java.lang.Thread
java.util.concurrent(jsr166)
Fork/Join Framework(jsr166y)
PConcurrency in Java
Phasers, etc(jsr166)
8/12/2019 Lamda Expressions Tutorial
3/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.3
Lambdas In Java
8/12/2019 Lamda Expressions Tutorial
4/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.4
The Problem: External Iteration
List students = ...
double highestScore = 0.0;
for (Student s : students) {
if (s.gradYear == 2011) {
if (s.score > highestScore) {
highestScore = s.score;
}
}
}
Client controls it Inherently serial
beginning to en
Not thread-safebusiness logic is
(mutable accum
variable)
8/12/2019 Lamda Expressions Tutorial
5/33Copyright 2012, Oracle and/or its affiliates. All rights reserved.5
Internal Iteration With Inner Classes
! Iteration, filtering anaccumulation are h
library
! Not inherently seriamaybe done in par
! Traversal maybe done pass, rather tha
! Thread safe clienstateless
! High barrier to use Syntactically ugly
More Functional, Fluent
List students = ...
double highestScore = students.
filter(new Predicate() {
public boolean op(Student s) {
return s.getGradYear() == 2011;
}
}).
map(new Mapper() {
public Double extract(Student s) {
return s.getScore();
}
}).
max();
8/12/2019 Lamda Expressions Tutorial
6/33Copyright 2012, Oracle and/or its affiliates. All rights reserved.6
Internal Iteration With Lambdas
SomeList students = ...
double highestScore = students.filter(Student s -> s.getGradYear() == 2011
map(Student s -> s.getScore()).
max(); More readab More abstra Less error-p No reliance Easier to ma
8/12/2019 Lamda Expressions Tutorial
7/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.7
Lambda Expressions
! Lambda expressions represent anonymous functions Like a method, has a typed argument list, a return type, a set
exceptions, and a body
Not associated with a class! We now have parameterised behaviour, not just values
Some Details
double highestScore = students.
filter(Students -> s.getGradYear() == 2011)
map(Student s -> s.getScore())
max();
What
How
8/12/2019 Lamda Expressions Tutorial
8/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.8
Lambda Expression Types
Single-method interfaces are used extensively in Java Definition: a functional interfaceis an interface with one abstra
! Not necessarily only one method Functional interfacesare identified structurally The typeof a lambda expression will be a functional interfaceinterface Comparator { boolean compare(T x, T y); }
interface FileFilter { boolean accept(File x); }
interface Runnable { void run(); }
interface ActionListener { void actionPerformed(); }
interface Callable { T call(); }
8/12/2019 Lamda Expressions Tutorial
9/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.9
Local Variable Capture
Lambda expressions can refer to effectively final local varithe enclosing scope Effectively final means that the variable meets the requirem
variables (i.e., assigned once), even if not explicitly declared
This is a form of type inferencevoid expire(File root, longbefore) {
root.listFiles(File p -> p.lastModified()
8/12/2019 Lamda Expressions Tutorial
10/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.10
Lexical Scoping
The meaning of names are the same inside the lambda as A this reference refers to the enclosing object, not the lam Think of this as a final predefined local Remember the type of a Lambda is a functionalinterface
class SessionManager {long before = ...;
void expire(File root) {
// refers to this.before, just like outside the lambdaroot.listFiles(File p -> checkExpiry(p.lastModified(), this.before
}
boolean checkExpiry(long time, long expiry) { ... }}
8/12/2019 Lamda Expressions Tutorial
11/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.11
Type Inferrence
! The compiler can often infer parameter types in a lambda e! Inferrence based on the target functional interfaces method! Fully statically typed (no dynamic typing sneaking in)
More typing with less typing
List ls = getList();Collections.sort(ls, (String x, String y) -> x.length() - y.le
Collections.sort(ls, (x, y) -> x.length() - y.length());
static T void sort(List l, Comparator
8/12/2019 Lamda Expressions Tutorial
12/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.12
Method References
Method references let us reuse a method as a lambda exp
FileFilter x = File f -> f.canRead();
FileFilter x = File::canRead;
8/12/2019 Lamda Expressions Tutorial
13/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.13
Constructor References
! Same concept as a method reference For the constructor
Factory f =ArrayList::new;
Factory f = () -> return newArrayList
Equivalent to
8/12/2019 Lamda Expressions Tutorial
14/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.14
Library Evolution
8/12/2019 Lamda Expressions Tutorial
15/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.15
Library Evolution Goal
!Requirement: aggregate operations on collections New methods required on Collections to facilitate this
!This is problematic Cant add new methods to interfaces without modifying all implem Cant necessarily find or control all implementations
int heaviestBlueBlock = blocks.
filter(b -> b.getColor() == BLUE).
map(Block::getWeight).
reduce(0, Integer::max);
8/12/2019 Lamda Expressions Tutorial
16/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.16
Solution: Extension Methods
Specified in the interface From the callers perspective, just an ordinary interface m Provides a default implementation
Default is only used when implementation classes do not provfor the extension method
Implementation classes can provide a better version, or not
AKA Defender Methods
interface Collection {
defaultStream stream() {
return StreamSupport.stream(spliterator());
}
}
8/12/2019 Lamda Expressions Tutorial
17/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.17
Virtual Extension Methods
Err, isnt this implementing multiple inheritance for Java?
Yes, but Java already has multiple inheritance of types This adds multiple inheritance of behaviortoo But not state, which is where most of the trouble is Can still be a source of complexity due to separate compilatio
dynamic linking Class implements two interfaces, both of which have defau Same signature How does the compiler differentiate?
Stop right there!
8/12/2019 Lamda Expressions Tutorial
18/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.18
Functional Interface Definition
!Single Abstract Method (SAM) type
!A functional interface is an interface that has one abstract m Represents a single function contract Doesnt mean it only has one method
!Abstract classes may be considered later!@FunctionalInterfaceannotation
Helps ensure the functional interface contract is honoured Compiler error if not a SAM
8/12/2019 Lamda Expressions Tutorial
19/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.19
Lambdas In Full Flow:
Streams
8/12/2019 Lamda Expressions Tutorial
20/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.20
Stream Overview
!A stream pipeline consists of three types of things
A source Zero or more intermediate operations A terminal operation
! Producing a result or a side-effect
Pipeline
int sum = transactions.stream().
filter(t -> t.getBuyer().getCity().equals(London)).
mapToInt(Transaction::getPrice).
sum();
Source
Intermedia
Terminal operation
8/12/2019 Lamda Expressions Tutorial
21/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.21
Stream Sources
!From collections and arrays
Collection.stream() Collection.parallelStream()Arrays.stream(T array)or Stream.of()
! Static factories IntStream.range() Files.walk()
! Roll your own java.util.Spliterator()
Many Ways To Create
8/12/2019 Lamda Expressions Tutorial
22/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.22
Stream Sources Provide
!Access to stream elements! Decomposition (for parallel operations)
Fork-join framework! Stream characteristics
ORDERED DISTINCT SORTED SIZED SUBSIZEDNONNULL IMMUTABLE CONCURRENT
8/12/2019 Lamda Expressions Tutorial
23/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.23
Stream Terminal Operations
!Invoking a terminal operation executes the pipeline
All operations can execute sequentially or in parallel! Terminal operations can take advantage of pipeline charact
toArray()can avoid copying for SIZEDpipelines by allocatadvance
8/12/2019 Lamda Expressions Tutorial
24/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.24
mapand flatMapMap Values in a Stream
!map(one to one)
Each element of the input stream is mapped to an element in stream
!flatMap(one to many) Each element of the input stream is mapped to a new stream Streams from all elements are concatenated to form one outp
8/12/2019 Lamda Expressions Tutorial
25/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.25
Example 1Convert words in list to upper case
List output = wordList.
stream().
map(String::toUpperCase).
collect(Collectors.toList());
8/12/2019 Lamda Expressions Tutorial
26/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.26
Example 2Find words in list with even length
List output = wordList.
stream().
filter(w -> (w.length() & 1 == 0).
collect(Collectors.toList());
8/12/2019 Lamda Expressions Tutorial
27/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.27
Example 3
!BufferedReader has new method
Stream lines()
Count lines in a file
long count = bufferedReader.
lines().
count();
8/12/2019 Lamda Expressions Tutorial
28/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.28
Example 4Join lines 3-4 into a single string
String output = bufferedReader.
lines().
skip(2).
limit(2).
collect(Collectors.joining());
8/12/2019 Lamda Expressions Tutorial
29/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.29
Example 5Find the length of the longest line in a file
int longest = reader.
lines().
mapToInt(String::length).
max().
getAsInt(); Returns an Optiona
8/12/2019 Lamda Expressions Tutorial
30/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.30
Example 6Collect all words in a file into a list
List output = reader.
lines().
flatMap(line -> Stream.of(line.split(REG
filter(word -> word.length() > 0).
collect(Collectors.toList());
8/12/2019 Lamda Expressions Tutorial
31/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.31
Example 7List of words lowercased, in aphabetical order
List output = reader.
lines().
flatMap(line -> Stream.of(line.split(REG
filter(word -> word.length() > 0).
map(String::toLowerCase).sorted().
collect(Collectors.toList());
8/12/2019 Lamda Expressions Tutorial
32/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.32
Conclusions
! Java needs lambda statements Significant improvements in existing libraries are required
! Require a mechanism for interface evolution Solution: virtual extension methods
! Bulk operations on Collections Much simpler with Lambdas
! Java SE 8 evolves the language, libraries, and VM together
8/12/2019 Lamda Expressions Tutorial
33/33
Copyright 2012, Oracle and/or its affiliates. All rights reserved.33
Graphic Section Divider