SlideShare a Scribd company logo
Java 8
Functional Programming
with Lambdas
Angelika Langer
Training/Consulting
http://www.AngelikaLanger.com/
objective

• learn about lambda expressions in Java
• know the syntax elements
• understand typical uses

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(2)
speaker's relationship to topic

• independent trainer / consultant / author
–
–
–
–
–
–

teaching C++ and Java for >15 years
curriculum of a couple of challenging courses
JCP observer and Java champion since 2005
co-author of "Effective Java" column
author of Java Generics FAQ online
author of Lambda Tutorial & Reference

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(3)
agenda

• lambda expression
• functional patterns

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(4)
lambda expressions in Java

• lambda expressions


formerly known as closures

• concept from functional programming languages
– anonymous method


“ad hoc” implementation of functionality

– code-as-data


pass functionality around (as parameter or return value)

– superior to (anonymous) inner classes


concise syntax + less code + more readable + “more functional”

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(5)
key goal

• build better (JDK) libraries
– e.g. for easy parallelization on multi core platforms

• collections shall have parallel bulk operations
– based on fork-join-framework
– execute functionality on a collection in parallel

• separation between "what to do" & "how to do"
– user
– library

=> what functionality to apply
=> how to apply functionality

(parallel/sequential, lazy/eager, out-of-order)
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(6)
today
private static void checkBalance(List<Account> accList) {
for (Account a : accList)
if (a.balance() < threshold) a.alert();
}

• for-loop uses an iterator:
Iterator iter = accList.iterator();
while (iter.hasNext()) {
Account a = iter.next();
if (a.balance() < threshold)
a.alert();
}

• code is inherently serial
– traversal logic is fixed
– iterate from beginning to end
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(7)
Stream.forEach() - definition

public interface Stream<T> ... {
...
void forEach(Consumer<? super T> consumer);
...
}

public interface Consumer<T> {
void accept(T t)
…
}

• forEach()’s iteration not inherently serial
– traversal order defined by forEach()’s implementation
– burden of parallelization put on library developer

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(8)
Stream.forEach() - example
Stream<Account> pAccs = accList.parallelStream();
// with anonymous inner class
pAccs.forEach( new Consumer<Account>() {
void accept(Account a) {
if (a.balance() < threshold) a.alert();
}
} );
// with lambda expression
pAccs.forEach( (Account a) ->
{ if (a.balance() < threshold) a.alert(); } );

• lambda expression
– less code (overhead)
– only actual functionality => easier to read

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(9)
agenda

• lambda expression
– functional interfaces
– lambda expressions (syntax)
– method references

• functional patterns

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(10)
is a lambda an object?

Consumer<Account> block =
(Account a) -> { if (a.balance() < threshold) a.alert(); };

• right side: lambda expression
• intuitively
– a lambda is "something functional"
takes an Account
 returns nothing (void)
 throws no checked exception
 has an implementation {body}
– kind of a function type: (Account)->void


• Java's type system does not have function types
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(11)
functional interface = target type of a lambda
interface Consumer<T> { public void accept(T a); }
Consumer<Account> pAccs =
(Account a) -> { if (a.balance() < threshold) a.alert(); };

• lambdas are converted to functional interfaces
– function interface := interface with one abstract method

• compiler infers target type
– relevant: parameter type(s), return type, checked exception(s)
– irrelevant: interface name + method name

• lambdas need a type inference context
– e.g. assignment, method/constructor arguments, return statements, cast
expression, …

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(12)
lambda expressions & functional interfaces

• functional interfaces
interface Consumer<T> { void accept(T a); }
interface MyInterface { void doWithAccount(Account a); }

• conversions
Consumer<Account> block =
(Account a) -> { if (a.balance() < threshold) a.alert(); };
MyInterface mi =
(Account a) -> { if (a.balance() < threshold) a.alert(); };
mi = block;

error: types are not compatible

• problems
error: cannot infer target type
Object o1 =
(Account a) -> { if (a.balance() < threshold) a.alert(); };

Object o2 = (Consumer<Account>)
(Account a) -> { if (a.balance() < threshold) a.alert(); };
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(13)
agenda

• lambda expression
– functional interfaces
– lambda expressions (syntax)
– method references

• functional patterns

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(14)
formal description

lambda = ArgList "->" Body
ArgList = Identifier
| "(" Identifier [ "," Identifier ]* ")"
| "(" Type Identifier [ "," Type Identifier ]* ")“
Body = Expression
| "{" [ Statement ";" ]+ "}"

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(15)
syntax samples
argument list
(int x, int y) -> { return x+y; }
(x, y) -> { return x+y; }
x -> { return x+1; }
() -> { System.out.println(“I am a Runnable”); }

body
// single statement or list of statements
a -> {
if (a.balance() < threshold) a.alert();
}
// single expression
a -> (a.balance() < threshold) ? a.alert() : a.okay()

return type (is always inferred)
(Account a) -> { return a; }
()
->
5
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

// returns Account
// returns int
Lambda Expressions in Java

(16)
local variable capture

int cnt = 16;
Runnable r = () -> { System.out.println(“count: ” + cnt); };
cnt++;

error: cnt is read-only

• local variable capture
– similar to anonymous inner classes

• no explicit final required
– implicitly final, i.e. read-only

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(17)
reason for "effectively final"
int cnt = 0;
Runnable r =
() -> { for (int j=0; j < 32; j++ ) cnt = j; };

error

// start Runnable r in another thread
threadPool.submit(r);
...
while (cnt <= 16) /* NOP */;
System.out.println(“cnt is now greater than 16”);

problems:
• unsynchronized concurrent access
– lack of memory model guaranties

• lifetime of local objects
– locals are no longer "local"
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(18)
the dubious "array boxing" hack
• to work around "effectively final" add another level of indirection
– i.e. use an effectively final reference to a mutable object
File myDir = ....
int[] r_cnt = new int[1];
File[] fs = myDir.listFiles( f -> {
if (f.isFile() {
n = f.getName();
if (n.lastIndexOf(“.exe”) == n.length()-4) r_cnt[0]++;
return true;
}
return false;
};);
System.out.println("contains " + r_cnt[0] + "exe-files");

• no problem, if everything is executed sequentially
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(19)
lambda body lexically scoped, pt. 1

• lambda body scoped in enclosing method
• effect on local variables:
– capture works as shown before
– no shadowing of lexical scope

lambda

int i = 16;
Runnable r = () -> { int i = 0;
System.out.println(“i is: ” + i); };

error

• different from inner classes
– inner class body is a scope of its own

inner class

final int i = 16;
Runnable r = new Runnable() {
public void run() { int i = 0;
System.out.println(“i is: ” + i); }
};
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

fine

Lambda Expressions in Java

(20)
lambdas vs. inner classes - differences

• local variable capture:
– implicitly final vs. explicitly final

• different scoping:
– this means different things

• verbosity:
– concise lambda syntax vs. inner classes' syntax overhead

• performance:
– lambdas slightly faster (use "invokedynamic" from JSR 292)

• bottom line:
– lambdas better than inner classes for functional types
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(22)
agenda

• lambda expression
– functional interfaces
– lambda expressions (syntax)
– method references

• functional patterns

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(23)
idea behind method references

• take an existing method (from some class), and
make it the implementation of a functional interface
– similar to lambda expressions

• need context that allows conversion to a target type
– similar to lambda expressions

• advantages (over lambdas)
– shows: reuse existing implementation
– less code

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(24)
lambda vs. method reference

// package java.util
public interface Stream<T> ... {
...
void forEach(Consumer<? super T> consumer);
...
}
// package java.uti.function
public interface Consumer<T> {
void accept(T t)
…
}
accounts.forEach(a -> a.addInterest());
accounts.forEach(Account::addInterest);

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(25)
method references

various forms of method references ...
• static method:

Type::MethodName

– e.g. System::currentTimeMillis

• constructor:

Type::new

– e.g. String::new

• non-static method w/ unbound receiver: Type::MethodName
– e.g. String::length

• non-static method w/ bound receiver:

Expr::Method

– e.g. System.out::println

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(26)
agenda

• lambda expression
• functional patterns
– internal iteration
– execute around

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(27)
external vs. internal iteration

• iterator pattern from GOF book
– distinguishes between external and internal iteration
– who controls the iteration?

• in Java, iterators are external
– collection user controls the iteration

• in functional languages, iterators are internal
– the collection itself controls the iteration
– with Java 8 collections will provide internal iteration

GOF (Gang of Four) book:
"Design Patterns: Elements of Reusable Object-Oriented Software", by Gamma, Helm, Johnson, Vlissides, Addison-Wesley 1994
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(28)
various ways of iterating
Collection<String> c = ...

< Java 5

Iterator<String> iter = c.iterator();
while (iter.hasNext())
System.out.println(iter.next() + ' ');

for(String s : c)
System.out.println(s + ' ');

Java 5

c.forEach(s -> System.out.println(s) + ' ');

Java 8

• internal iteration in Java 8
– separates iteration from applied functionality
– Java 5 for-each loop already comes close to it
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(29)
Java 8 design (diagram)

Iterable
iterator()
forEach()

Collection

stream()
parallelStream()

Stream
forEach()
filter()
map()
reduce()
...

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(30)
filter/map/reduce in Java 8
• for-each
apply a certain functionality to each element of the collection
accounts.forEach(a -> a.addInterest());

• filter
build a new collection that is the result of a filter applied to each
element in the original collection
Stream<Account> result =
accounts.filter(a -> a.balance()>1000000?true:false);

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(31)
filter/map/reduce (cont.)
• map
build a new collection, where each element is the result of a
mapping from an element of the original collection
IntStream result = accounts.map(a -> a.balance());

• reduce
produce a single result from all elements of the collection
int sum = accounts.map(a -> a.balance())
.reduce(0, (b1, b2) -> b1 + b2);

• and many more:

sorted(), anyMatch(), flatMap(), …

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(32)
what is a stream?

• view/adaptor of a data source (collection, array, …)
– class java.util.stream.Stream<T>
– class java.util.stream.IntStream

• a stream has no storage => a stream is not a collection
– supports forEach/filter/map/reduce functionality as shown before

• stream operations are "functional"
– produce a result
– do not alter the underlying collection

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(33)
fluent programming

• streams support fluent programming
– operations return objects on which further operations are invoked
– e.g. stream operations return a stream

interface Stream<T> {
Stream<T> filter (Predicate<? super T> predicate);
<R> Stream<R> map
(Function<? super T,? extends R> mapper);
...
}

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(34)
intermediate result / lazy operation

• bulk operations that return a stream are
intermediate / lazy
Stream<Integer> ints5Added
= ints.stream().filter(i -> i > 0).map(i -> i + 5);

• resulting Stream contains references to
– original List ints, and
– a MapOp operation object


together with its parameter (the lambda expression)

• the operation is applied later
– when a terminal operation occurs
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(35)
terminal operation

• a terminal operation does not return a stream
– triggers evaluation of the intermediate stream
Stream<Integer> ints5Added
= ints.stream().filter(i->i>0).map(i->i+5);
List<Integer> result = ints5Added.collect(Collectors.toList());

– or in fluent programming notation:
List<Integer> result = ints.stream()
.filter(i->i>0)
.map(i->i+5)
.collect(Collectors.toList());

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(36)
more pitfalls - one-pass

No!

Stream<Integer> ints5Added
= ints.stream().filter(i->i>0).map(i->i+5);
ints5Added.forEach(i -> System.out.print(i + " "));
System.out.println("sum is: " +
ints5Added.reduce(0, (i, j) -> i+j));

6 7 8 9 10 11 12 13
Exception in thread "main"
java.lang.IllegalStateException: Stream source is already consumed

• stream elements can only be consumed once
– like bytes from an input stream
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(37)
fluent approach

Yes!

System.out.println("sum is: " +
ints.stream()
.map(i -> i + 5);
.peek(i -> System.out.print(i + " "))
.reduce(0, (i, j) -> i+j)
);
6 7 8 9 10 11 12 13 sum is: 76

• use intermediate peek operation
– instead of a terminal forEach operation

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(38)
agenda

• lambda expression
• functional patterns
– internal iteration
– execute around

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(39)
execute-around (method) pattern/idiom

• situation
public void handleInput(String fileName) throws IOException {
InputStream is = new FileInputStream(fileName);
try {
... use file stream ...
} finally {
is.close();
}
}

• factor the code into two parts
– the general "around" part
– the specific functionality


passed in as lambda parameter

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(40)
execute-around pattern (cont.)

• clumsy to achieve with procedural programming
– maybe with reflection, but feels awkward

• typical examples
– acquisition + release
– using the methods of an API/service (+error handling)
– …

• blends into: user defined control structures

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(41)
object monitor lock vs. explicit lock

implicit lock

Object lock = new Object();
synchronized (lock) {
... critical region ...
}

explicit lock

Lock lock = new ReentrantLock();
lock.lock();
try {
... critical region ...
} finally {
lock.unlock();
}

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(42)
helper class Utils

• split into a functional type and a helper method
public class Utils {
@FunctionalInterface
public interface CriticalRegion {
void apply();
}
public static void withLock(Lock lock, CriticalRegion cr) {
lock.lock();
try {
cr.apply();
} finally {
lock.unlock();
}
}
}

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(43)
example: thread-safe MyIntStack

• user code
private class MyIntStack {
private Lock lock = new ReentrantLock();
private int[] array = new int[16];
private int sp = -1;
public void push(int e) {
withLock(lock, () -> {
if (++sp >= array.length)
resize();
array[sp] = e;
});
}

lambda converted
to functional type
CriticalRegion

...

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(44)
example : thread-safe MyIntStack (cont.)

• more user code
...
public int pop() {
withLock(lock, () -> {
if (sp < 0)
throw new NoSuchElementException();
else
return array[sp--];
local return from lambda
});
}
}

• error:
– CriticalRegion::apply does

not permit return value
– return in lambda is local, i.e., returns from lambda, not from pop

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(45)
signature of CriticalRegion
• CriticalRegion has signature:
public interface CriticalRegion {
void apply();
}

• but we also need this signature
– in order to avoid array boxing hack
public interface CriticalRegion<T> {
T apply();
}

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(46)
signature of CriticalRegion (cont.)

• which requires an corresponding withLock() helper
public static <T> T withLock(Lock lock,
CriticalRegion<? extends T> cr) {
lock.lock();
try {
return cr.apply();
} finally {
lock.unlock();
}
} }

• which simplifies the pop() method
public int pop() {
return withLock(lock, () -> {
if (sp < 0)
throw new NoSuchElementException();

}

return (array[sp--]);
});

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(47)
signature of CriticalRegion (cont.)

• but creates problems for the push() method
– which originally returns void
– and now must return a ‘fake’ value from it’s critical region

• best solution (for the user code):
– two interfaces:

VoidRegion,
GenericRegion<T>

– plus two overloaded methods:
void

withLock(Lock l, VoidRegion

cr)

<T> T withLock(Lock l, GenericRegion<? extends T> cr)

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(48)
arguments are no problem

• input data can be captured
– independent of number and type
– reason: read-only
public void push(final int e) {
withLock(lock, () -> {
if (++sp >= array.length)
resize();
array[sp] = e;
});

method argument
is captured

}

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(49)
coping with exceptions

• only runtime exceptions are fine
public int pop() {
return withLock(lock, () -> {
if (sp < 0)
throw new NoSuchElementException();
return (array[sp--]);
});
}

– exactly what we want:
pop() throws NoSuchElementException when stack is empty

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(50)
checked exception problem

• checked exceptions cause trouble
– CriticalRegion's method must not throw
void myMethod() throws IOException {
withLock(lock, () ->
{
... throws IOException ...
}

error

});

– how can we propagate checked exception thrown by lambda
back to surrounding user code ?

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(51)
tunnelling vs. transparency

• two options for propagation:
– wrap it in a RuntimeException (a kind of "tunnelling"), or
– transparently pass it back as is => exception transparency

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(52)
"tunnelling"

• wrap checked exception into unchecked exception
– messes up the user code
void myMethod() throws IOException {
try { withLock(lock, () ->
{ try {
... throws IOException ...
}
catch (IOException ioe) {
throw new RuntimeException(ioe);
}
});
} catch (RuntimeException re) {
Throwable cause = re.getCause();
if (cause instanceof IOException)
throw ((IOException) cause);
else
throw re;
}
}
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

wrap

unwrap

Lambda Expressions in Java

(53)
self-made exception transparency

• declare functional interfaces with checked exceptions
– reduces user-side effort significantly
– functional type declares the checked exception(s):
public interface VoidIOERegion {
void apply() throws IOException;
}

– helper method declares the checked exception(s):
public static void withLockAndIOException
(Lock lock, VoidIOERegion cr) throws IOException {
lock.lock();
try {
cr.apply();
} finally {
lock.unlock();
}
} }
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(54)
self-made exception transparency (cont.)
– user code simply throws checked exception
void myMethod() throws IOException {
withLockAndIOException(lock, () -> {
... throws IOException ...
});
}

caveat:
– only reasonable, when exception closely related to functional type
closely related = is typically thrown from the code block
not true in our example
just for illustration of the principle


© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(55)
wrap-up execute around / control structures

• factor code into
– the general around part, and
– the specific functionality


passed in as lambda parameter

• limitations
– regarding checked exceptions & return type


due to strong typing in Java

– is not the primary goal for lambdas in Java 8
– nonetheless quite useful in certain situations

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(56)
authors

Angelika Langer & Klaus Kreft
http://www.AngelikaLanger.com
twitter: @AngelikaLanger

related reading:
Lambda & Streams Tutorial/Reference
AngelikaLanger.comLambdasLambdas.html

related seminar:
Programming with Lambdas & Streams in Java 8
Angelikalanger.comCoursesLambdasStreams.html
© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(57)
stream workshop

Q&A

© Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved.
http://www.AngelikaLanger.com/
last update: 12/6/2013,11:26

Lambda Expressions in Java

(58)

More Related Content

PDF
Lambda Expressions in Java
PPTX
Java 8 lambda
PDF
Java 8 - Project Lambda
PDF
Java 8 lambda expressions
PPTX
Java 8 Lambda Expressions
PPTX
Java 8 Lambda and Streams
PDF
Java 8 Lambda Expressions & Streams
PPTX
Java 8 presentation
Lambda Expressions in Java
Java 8 lambda
Java 8 - Project Lambda
Java 8 lambda expressions
Java 8 Lambda Expressions
Java 8 Lambda and Streams
Java 8 Lambda Expressions & Streams
Java 8 presentation

What's hot (20)

PPTX
Java 8 - Features Overview
PDF
Java8 features
PPTX
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
PPTX
Lambda Expressions in Java 8
PDF
PDF
Java 8 features
PPTX
java 8 new features
PPT
Major Java 8 features
PPTX
Java 8 Feature Preview
PPTX
Java 8 streams
PPTX
The Dark Side Of Lambda Expressions in Java 8
PDF
Java 8 Lambda Expressions
PDF
Functional programming in java 8 by harmeet singh
PDF
Java 8: the good parts!
PPTX
Java SE 8 - New Features
PPTX
Java 8 new features
PDF
Streams in Java 8
PPTX
Actors model in gpars
ODP
Introduction to Java 8
KEY
Scala: functional programming for the imperative mind
Java 8 - Features Overview
Java8 features
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Lambda Expressions in Java 8
Java 8 features
java 8 new features
Major Java 8 features
Java 8 Feature Preview
Java 8 streams
The Dark Side Of Lambda Expressions in Java 8
Java 8 Lambda Expressions
Functional programming in java 8 by harmeet singh
Java 8: the good parts!
Java SE 8 - New Features
Java 8 new features
Streams in Java 8
Actors model in gpars
Introduction to Java 8
Scala: functional programming for the imperative mind
Ad

Viewers also liked (11)

PDF
Stateless authentication for microservices - Spring I/O 2015
PDF
OAuth2 and Spring Security
PDF
Reactive app using actor model & apache spark
PDF
Swift Generics in Theory and Practice
PDF
Java Generics: a deep dive
PDF
Java Generics Introduction - Syntax Advantages and Pitfalls
PPTX
Reactive Streams and RabbitMQ
PPTX
Introduction to Regular Expressions
KEY
Regular Expressions 101
PDF
Lecture: Regular Expressions and Regular Languages
PDF
Consumer Driven Contracts and Your Microservice Architecture
Stateless authentication for microservices - Spring I/O 2015
OAuth2 and Spring Security
Reactive app using actor model & apache spark
Swift Generics in Theory and Practice
Java Generics: a deep dive
Java Generics Introduction - Syntax Advantages and Pitfalls
Reactive Streams and RabbitMQ
Introduction to Regular Expressions
Regular Expressions 101
Lecture: Regular Expressions and Regular Languages
Consumer Driven Contracts and Your Microservice Architecture
Ad

Similar to Programming with Lambda Expressions in Java (20)

PDF
Jf12 lambdas injava8-1
PPTX
New features in jdk8 iti
PDF
Java 8
PPT
Scala Talk at FOSDEM 2009
PPTX
Functional Programming With Lambdas and Streams in JDK8
PPTX
Lambdas and Laughs
PPTX
Eclipse Day India 2015 - Java 8 Overview
PPTX
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
PPTX
New Features in JDK 8
PDF
Charles Sharp: Java 8 Streams
PDF
Lambdas & Streams
PDF
How We UITest with GraphQL
PDF
Effective Java, Third Edition - Keepin' it Effective
PDF
Apouc 2014-java-8-create-the-future
ODP
Lambda Chops - Recipes for Simpler, More Expressive Code
PDF
Project Lambda: To Multicore and Beyond
PDF
Java 8 Overview
PDF
Short intro to scala and the play framework
PPTX
Java gets a closure
PDF
Serverless Architecture - A Gentle Overview
Jf12 lambdas injava8-1
New features in jdk8 iti
Java 8
Scala Talk at FOSDEM 2009
Functional Programming With Lambdas and Streams in JDK8
Lambdas and Laughs
Eclipse Day India 2015 - Java 8 Overview
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
New Features in JDK 8
Charles Sharp: Java 8 Streams
Lambdas & Streams
How We UITest with GraphQL
Effective Java, Third Edition - Keepin' it Effective
Apouc 2014-java-8-create-the-future
Lambda Chops - Recipes for Simpler, More Expressive Code
Project Lambda: To Multicore and Beyond
Java 8 Overview
Short intro to scala and the play framework
Java gets a closure
Serverless Architecture - A Gentle Overview

Recently uploaded (20)

PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPT
Teaching material agriculture food technology
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
cuic standard and advanced reporting.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Approach and Philosophy of On baking technology
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
MIND Revenue Release Quarter 2 2025 Press Release
Chapter 3 Spatial Domain Image Processing.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Empathic Computing: Creating Shared Understanding
Digital-Transformation-Roadmap-for-Companies.pptx
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Teaching material agriculture food technology
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Programs and apps: productivity, graphics, security and other tools
The Rise and Fall of 3GPP – Time for a Sabbatical?
cuic standard and advanced reporting.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Approach and Philosophy of On baking technology
Building Integrated photovoltaic BIPV_UPV.pdf

Programming with Lambda Expressions in Java

  • 1. Java 8 Functional Programming with Lambdas Angelika Langer Training/Consulting http://www.AngelikaLanger.com/
  • 2. objective • learn about lambda expressions in Java • know the syntax elements • understand typical uses © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (2)
  • 3. speaker's relationship to topic • independent trainer / consultant / author – – – – – – teaching C++ and Java for >15 years curriculum of a couple of challenging courses JCP observer and Java champion since 2005 co-author of "Effective Java" column author of Java Generics FAQ online author of Lambda Tutorial & Reference © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (3)
  • 4. agenda • lambda expression • functional patterns © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (4)
  • 5. lambda expressions in Java • lambda expressions  formerly known as closures • concept from functional programming languages – anonymous method  “ad hoc” implementation of functionality – code-as-data  pass functionality around (as parameter or return value) – superior to (anonymous) inner classes  concise syntax + less code + more readable + “more functional” © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (5)
  • 6. key goal • build better (JDK) libraries – e.g. for easy parallelization on multi core platforms • collections shall have parallel bulk operations – based on fork-join-framework – execute functionality on a collection in parallel • separation between "what to do" & "how to do" – user – library => what functionality to apply => how to apply functionality (parallel/sequential, lazy/eager, out-of-order) © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (6)
  • 7. today private static void checkBalance(List<Account> accList) { for (Account a : accList) if (a.balance() < threshold) a.alert(); } • for-loop uses an iterator: Iterator iter = accList.iterator(); while (iter.hasNext()) { Account a = iter.next(); if (a.balance() < threshold) a.alert(); } • code is inherently serial – traversal logic is fixed – iterate from beginning to end © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (7)
  • 8. Stream.forEach() - definition public interface Stream<T> ... { ... void forEach(Consumer<? super T> consumer); ... } public interface Consumer<T> { void accept(T t) … } • forEach()’s iteration not inherently serial – traversal order defined by forEach()’s implementation – burden of parallelization put on library developer © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (8)
  • 9. Stream.forEach() - example Stream<Account> pAccs = accList.parallelStream(); // with anonymous inner class pAccs.forEach( new Consumer<Account>() { void accept(Account a) { if (a.balance() < threshold) a.alert(); } } ); // with lambda expression pAccs.forEach( (Account a) -> { if (a.balance() < threshold) a.alert(); } ); • lambda expression – less code (overhead) – only actual functionality => easier to read © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (9)
  • 10. agenda • lambda expression – functional interfaces – lambda expressions (syntax) – method references • functional patterns © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (10)
  • 11. is a lambda an object? Consumer<Account> block = (Account a) -> { if (a.balance() < threshold) a.alert(); }; • right side: lambda expression • intuitively – a lambda is "something functional" takes an Account  returns nothing (void)  throws no checked exception  has an implementation {body} – kind of a function type: (Account)->void  • Java's type system does not have function types © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (11)
  • 12. functional interface = target type of a lambda interface Consumer<T> { public void accept(T a); } Consumer<Account> pAccs = (Account a) -> { if (a.balance() < threshold) a.alert(); }; • lambdas are converted to functional interfaces – function interface := interface with one abstract method • compiler infers target type – relevant: parameter type(s), return type, checked exception(s) – irrelevant: interface name + method name • lambdas need a type inference context – e.g. assignment, method/constructor arguments, return statements, cast expression, … © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (12)
  • 13. lambda expressions & functional interfaces • functional interfaces interface Consumer<T> { void accept(T a); } interface MyInterface { void doWithAccount(Account a); } • conversions Consumer<Account> block = (Account a) -> { if (a.balance() < threshold) a.alert(); }; MyInterface mi = (Account a) -> { if (a.balance() < threshold) a.alert(); }; mi = block; error: types are not compatible • problems error: cannot infer target type Object o1 = (Account a) -> { if (a.balance() < threshold) a.alert(); }; Object o2 = (Consumer<Account>) (Account a) -> { if (a.balance() < threshold) a.alert(); }; © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (13)
  • 14. agenda • lambda expression – functional interfaces – lambda expressions (syntax) – method references • functional patterns © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (14)
  • 15. formal description lambda = ArgList "->" Body ArgList = Identifier | "(" Identifier [ "," Identifier ]* ")" | "(" Type Identifier [ "," Type Identifier ]* ")“ Body = Expression | "{" [ Statement ";" ]+ "}" © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (15)
  • 16. syntax samples argument list (int x, int y) -> { return x+y; } (x, y) -> { return x+y; } x -> { return x+1; } () -> { System.out.println(“I am a Runnable”); } body // single statement or list of statements a -> { if (a.balance() < threshold) a.alert(); } // single expression a -> (a.balance() < threshold) ? a.alert() : a.okay() return type (is always inferred) (Account a) -> { return a; } () -> 5 © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 // returns Account // returns int Lambda Expressions in Java (16)
  • 17. local variable capture int cnt = 16; Runnable r = () -> { System.out.println(“count: ” + cnt); }; cnt++; error: cnt is read-only • local variable capture – similar to anonymous inner classes • no explicit final required – implicitly final, i.e. read-only © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (17)
  • 18. reason for "effectively final" int cnt = 0; Runnable r = () -> { for (int j=0; j < 32; j++ ) cnt = j; }; error // start Runnable r in another thread threadPool.submit(r); ... while (cnt <= 16) /* NOP */; System.out.println(“cnt is now greater than 16”); problems: • unsynchronized concurrent access – lack of memory model guaranties • lifetime of local objects – locals are no longer "local" © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (18)
  • 19. the dubious "array boxing" hack • to work around "effectively final" add another level of indirection – i.e. use an effectively final reference to a mutable object File myDir = .... int[] r_cnt = new int[1]; File[] fs = myDir.listFiles( f -> { if (f.isFile() { n = f.getName(); if (n.lastIndexOf(“.exe”) == n.length()-4) r_cnt[0]++; return true; } return false; };); System.out.println("contains " + r_cnt[0] + "exe-files"); • no problem, if everything is executed sequentially © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (19)
  • 20. lambda body lexically scoped, pt. 1 • lambda body scoped in enclosing method • effect on local variables: – capture works as shown before – no shadowing of lexical scope lambda int i = 16; Runnable r = () -> { int i = 0; System.out.println(“i is: ” + i); }; error • different from inner classes – inner class body is a scope of its own inner class final int i = 16; Runnable r = new Runnable() { public void run() { int i = 0; System.out.println(“i is: ” + i); } }; © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 fine Lambda Expressions in Java (20)
  • 21. lambdas vs. inner classes - differences • local variable capture: – implicitly final vs. explicitly final • different scoping: – this means different things • verbosity: – concise lambda syntax vs. inner classes' syntax overhead • performance: – lambdas slightly faster (use "invokedynamic" from JSR 292) • bottom line: – lambdas better than inner classes for functional types © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (22)
  • 22. agenda • lambda expression – functional interfaces – lambda expressions (syntax) – method references • functional patterns © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (23)
  • 23. idea behind method references • take an existing method (from some class), and make it the implementation of a functional interface – similar to lambda expressions • need context that allows conversion to a target type – similar to lambda expressions • advantages (over lambdas) – shows: reuse existing implementation – less code © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (24)
  • 24. lambda vs. method reference // package java.util public interface Stream<T> ... { ... void forEach(Consumer<? super T> consumer); ... } // package java.uti.function public interface Consumer<T> { void accept(T t) … } accounts.forEach(a -> a.addInterest()); accounts.forEach(Account::addInterest); © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (25)
  • 25. method references various forms of method references ... • static method: Type::MethodName – e.g. System::currentTimeMillis • constructor: Type::new – e.g. String::new • non-static method w/ unbound receiver: Type::MethodName – e.g. String::length • non-static method w/ bound receiver: Expr::Method – e.g. System.out::println © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (26)
  • 26. agenda • lambda expression • functional patterns – internal iteration – execute around © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (27)
  • 27. external vs. internal iteration • iterator pattern from GOF book – distinguishes between external and internal iteration – who controls the iteration? • in Java, iterators are external – collection user controls the iteration • in functional languages, iterators are internal – the collection itself controls the iteration – with Java 8 collections will provide internal iteration GOF (Gang of Four) book: "Design Patterns: Elements of Reusable Object-Oriented Software", by Gamma, Helm, Johnson, Vlissides, Addison-Wesley 1994 © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (28)
  • 28. various ways of iterating Collection<String> c = ... < Java 5 Iterator<String> iter = c.iterator(); while (iter.hasNext()) System.out.println(iter.next() + ' '); for(String s : c) System.out.println(s + ' '); Java 5 c.forEach(s -> System.out.println(s) + ' '); Java 8 • internal iteration in Java 8 – separates iteration from applied functionality – Java 5 for-each loop already comes close to it © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (29)
  • 29. Java 8 design (diagram) Iterable iterator() forEach() Collection stream() parallelStream() Stream forEach() filter() map() reduce() ... © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (30)
  • 30. filter/map/reduce in Java 8 • for-each apply a certain functionality to each element of the collection accounts.forEach(a -> a.addInterest()); • filter build a new collection that is the result of a filter applied to each element in the original collection Stream<Account> result = accounts.filter(a -> a.balance()>1000000?true:false); © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (31)
  • 31. filter/map/reduce (cont.) • map build a new collection, where each element is the result of a mapping from an element of the original collection IntStream result = accounts.map(a -> a.balance()); • reduce produce a single result from all elements of the collection int sum = accounts.map(a -> a.balance()) .reduce(0, (b1, b2) -> b1 + b2); • and many more: sorted(), anyMatch(), flatMap(), … © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (32)
  • 32. what is a stream? • view/adaptor of a data source (collection, array, …) – class java.util.stream.Stream<T> – class java.util.stream.IntStream • a stream has no storage => a stream is not a collection – supports forEach/filter/map/reduce functionality as shown before • stream operations are "functional" – produce a result – do not alter the underlying collection © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (33)
  • 33. fluent programming • streams support fluent programming – operations return objects on which further operations are invoked – e.g. stream operations return a stream interface Stream<T> { Stream<T> filter (Predicate<? super T> predicate); <R> Stream<R> map (Function<? super T,? extends R> mapper); ... } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (34)
  • 34. intermediate result / lazy operation • bulk operations that return a stream are intermediate / lazy Stream<Integer> ints5Added = ints.stream().filter(i -> i > 0).map(i -> i + 5); • resulting Stream contains references to – original List ints, and – a MapOp operation object  together with its parameter (the lambda expression) • the operation is applied later – when a terminal operation occurs © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (35)
  • 35. terminal operation • a terminal operation does not return a stream – triggers evaluation of the intermediate stream Stream<Integer> ints5Added = ints.stream().filter(i->i>0).map(i->i+5); List<Integer> result = ints5Added.collect(Collectors.toList()); – or in fluent programming notation: List<Integer> result = ints.stream() .filter(i->i>0) .map(i->i+5) .collect(Collectors.toList()); © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (36)
  • 36. more pitfalls - one-pass No! Stream<Integer> ints5Added = ints.stream().filter(i->i>0).map(i->i+5); ints5Added.forEach(i -> System.out.print(i + " ")); System.out.println("sum is: " + ints5Added.reduce(0, (i, j) -> i+j)); 6 7 8 9 10 11 12 13 Exception in thread "main" java.lang.IllegalStateException: Stream source is already consumed • stream elements can only be consumed once – like bytes from an input stream © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (37)
  • 37. fluent approach Yes! System.out.println("sum is: " + ints.stream() .map(i -> i + 5); .peek(i -> System.out.print(i + " ")) .reduce(0, (i, j) -> i+j) ); 6 7 8 9 10 11 12 13 sum is: 76 • use intermediate peek operation – instead of a terminal forEach operation © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (38)
  • 38. agenda • lambda expression • functional patterns – internal iteration – execute around © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (39)
  • 39. execute-around (method) pattern/idiom • situation public void handleInput(String fileName) throws IOException { InputStream is = new FileInputStream(fileName); try { ... use file stream ... } finally { is.close(); } } • factor the code into two parts – the general "around" part – the specific functionality  passed in as lambda parameter © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (40)
  • 40. execute-around pattern (cont.) • clumsy to achieve with procedural programming – maybe with reflection, but feels awkward • typical examples – acquisition + release – using the methods of an API/service (+error handling) – … • blends into: user defined control structures © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (41)
  • 41. object monitor lock vs. explicit lock implicit lock Object lock = new Object(); synchronized (lock) { ... critical region ... } explicit lock Lock lock = new ReentrantLock(); lock.lock(); try { ... critical region ... } finally { lock.unlock(); } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (42)
  • 42. helper class Utils • split into a functional type and a helper method public class Utils { @FunctionalInterface public interface CriticalRegion { void apply(); } public static void withLock(Lock lock, CriticalRegion cr) { lock.lock(); try { cr.apply(); } finally { lock.unlock(); } } } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (43)
  • 43. example: thread-safe MyIntStack • user code private class MyIntStack { private Lock lock = new ReentrantLock(); private int[] array = new int[16]; private int sp = -1; public void push(int e) { withLock(lock, () -> { if (++sp >= array.length) resize(); array[sp] = e; }); } lambda converted to functional type CriticalRegion ... © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (44)
  • 44. example : thread-safe MyIntStack (cont.) • more user code ... public int pop() { withLock(lock, () -> { if (sp < 0) throw new NoSuchElementException(); else return array[sp--]; local return from lambda }); } } • error: – CriticalRegion::apply does not permit return value – return in lambda is local, i.e., returns from lambda, not from pop © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (45)
  • 45. signature of CriticalRegion • CriticalRegion has signature: public interface CriticalRegion { void apply(); } • but we also need this signature – in order to avoid array boxing hack public interface CriticalRegion<T> { T apply(); } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (46)
  • 46. signature of CriticalRegion (cont.) • which requires an corresponding withLock() helper public static <T> T withLock(Lock lock, CriticalRegion<? extends T> cr) { lock.lock(); try { return cr.apply(); } finally { lock.unlock(); } } } • which simplifies the pop() method public int pop() { return withLock(lock, () -> { if (sp < 0) throw new NoSuchElementException(); } return (array[sp--]); }); © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (47)
  • 47. signature of CriticalRegion (cont.) • but creates problems for the push() method – which originally returns void – and now must return a ‘fake’ value from it’s critical region • best solution (for the user code): – two interfaces: VoidRegion, GenericRegion<T> – plus two overloaded methods: void withLock(Lock l, VoidRegion cr) <T> T withLock(Lock l, GenericRegion<? extends T> cr) © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (48)
  • 48. arguments are no problem • input data can be captured – independent of number and type – reason: read-only public void push(final int e) { withLock(lock, () -> { if (++sp >= array.length) resize(); array[sp] = e; }); method argument is captured } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (49)
  • 49. coping with exceptions • only runtime exceptions are fine public int pop() { return withLock(lock, () -> { if (sp < 0) throw new NoSuchElementException(); return (array[sp--]); }); } – exactly what we want: pop() throws NoSuchElementException when stack is empty © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (50)
  • 50. checked exception problem • checked exceptions cause trouble – CriticalRegion's method must not throw void myMethod() throws IOException { withLock(lock, () -> { ... throws IOException ... } error }); – how can we propagate checked exception thrown by lambda back to surrounding user code ? © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (51)
  • 51. tunnelling vs. transparency • two options for propagation: – wrap it in a RuntimeException (a kind of "tunnelling"), or – transparently pass it back as is => exception transparency © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (52)
  • 52. "tunnelling" • wrap checked exception into unchecked exception – messes up the user code void myMethod() throws IOException { try { withLock(lock, () -> { try { ... throws IOException ... } catch (IOException ioe) { throw new RuntimeException(ioe); } }); } catch (RuntimeException re) { Throwable cause = re.getCause(); if (cause instanceof IOException) throw ((IOException) cause); else throw re; } } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 wrap unwrap Lambda Expressions in Java (53)
  • 53. self-made exception transparency • declare functional interfaces with checked exceptions – reduces user-side effort significantly – functional type declares the checked exception(s): public interface VoidIOERegion { void apply() throws IOException; } – helper method declares the checked exception(s): public static void withLockAndIOException (Lock lock, VoidIOERegion cr) throws IOException { lock.lock(); try { cr.apply(); } finally { lock.unlock(); } } } © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (54)
  • 54. self-made exception transparency (cont.) – user code simply throws checked exception void myMethod() throws IOException { withLockAndIOException(lock, () -> { ... throws IOException ... }); } caveat: – only reasonable, when exception closely related to functional type closely related = is typically thrown from the code block not true in our example just for illustration of the principle  © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (55)
  • 55. wrap-up execute around / control structures • factor code into – the general around part, and – the specific functionality  passed in as lambda parameter • limitations – regarding checked exceptions & return type  due to strong typing in Java – is not the primary goal for lambdas in Java 8 – nonetheless quite useful in certain situations © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (56)
  • 56. authors Angelika Langer & Klaus Kreft http://www.AngelikaLanger.com twitter: @AngelikaLanger related reading: Lambda & Streams Tutorial/Reference AngelikaLanger.comLambdasLambdas.html related seminar: Programming with Lambdas & Streams in Java 8 Angelikalanger.comCoursesLambdasStreams.html © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (57)
  • 57. stream workshop Q&A © Copyright 2003-2013 by Angelika Langer & Klaus Kreft. All Rights Reserved. http://www.AngelikaLanger.com/ last update: 12/6/2013,11:26 Lambda Expressions in Java (58)