Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Â
Lambdas And Streams in JDK8
1.
2. 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.
3. 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
5. Lambdas
In
Java
Copyright
Š
2014,
Oracle
and/or
its
affiliates.
All
rights
reserved.
6. 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
7. 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();
8. 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
9. 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
10. 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();
}
11. 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);
}
12. 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
13. 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++));
}
}
14. 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
15. 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
16. 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;
17. 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;
19. 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
20. 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());
}
}
21. 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
22. 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
23. Lambdas
In
Full
Flow:
Streams
Copyright
Š
2014,
Oracle
and/or
its
affiliates.
All
rights
reserved.
24. 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
25. 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
26. 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
27. 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
28. 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
29. 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
30. 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
31. 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();
}
}
32. 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());
33. 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());
34. 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.
35. 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();
36. 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());
37. 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());
38. 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.
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()
-Ââ
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.
40. 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.
41. 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
42. Simon
Ri6er
Oracle
CorporarTon
Twi6er:
@speakjava
Copyright
Š
2014,
Oracle
and/or
its
affiliates.
All
rights
reserved.