SlideShare a Scribd company logo
Common mistakes made
with Functional Java
Brian Vermeer (@BrianVerm)
Brian Vermeer
Software Engineer
Doing too much in a single lambda
Lambda Expression
In computer programming, a lambda expression is a function definition
that is not bound to an identifier. Anonymous functions are often:[1]
• arguments being passed to higher-order functions, or
• used for constructing the result of a higher-order function that
needs to return a function.
Lambda in Java
Anonymous Inner functions
Satisfy a Functional Interface
They only exist in runtime
Single Line <input> -> <output> or Block <input> -> { function body }
Example
public void execute() {
Beer grolsch = new Beer("Grolsche", 4.3);
String result = handleBeer(grolsch,
beer -> grolsch.getName() + "-" + grolsch.getAlcohol());
System.out.println(result);
}
private String handleBeer(Beer beer, Function<Beer, String> func) {
System.out.println("handling beer " + beer.getName());
return func.apply(beer);
}
//Output : Grolsche-4.3
Example
public void execute() {
Beer grolsch = new Beer("Grolsche", 4.3);
String result = handleBeer(grolsch,
beer -> grolsch.getName() + "-" + grolsch.getAlcohol());
System.out.println(result);
}
private String handleBeer(Beer beer, Function<Beer, String> func) {
System.out.println("handling beer " + beer.getName());
return func.apply(beer);
}
//Output : Grolsche-4.3
Don’t do Block Lambda
beer -> {
String name;
if (beer.getName().contains(" ")) {
name = beer.getName().replace(" ", "");
} else {
name = beer.getName();
}
try {
name += Integer.parseInt(beer.getAlcoholPrecentage().toString());
} catch (NumberFormatException nfe) {
name += beer.getAlcoholPrecentage();
}
return name;
}
Transform to a methode
private String createFullName (Beer beer){
String name;
if (beer.getName().contains(" ")) {
name = beer.getName().replace(" ", "");
} else {
name = beer.getName();
}
try {
name += Integer.parseInt(beer.getAlcoholPrecentage().toString());
} catch (NumberFormatException nfe) {
name += beer.getAlcoholPrecentage();
}
return name;
}
handleBeer(grolsch, this::createFullName);
Returning a Stream
A stream is NOT a
data structure
A stream is NOT a
data structure
A stream is NOT a
data structure
What is Stream ( in Java)
Flow of data derived from a Collection
Can create a pipeline of function that can be evaluated
Intermediate result
Lazy evaluated by nature
Can transform data, cannot mutate data
JAVA Streams
stringLists.stream()

.map(str -> str.toUpperCase())

.collect(Collectors.toList());
Intermediate
filter 

distinct

map 

flatMap

Terminal
reduce

collect

toArray

count

max

min

limit 

skip

sorted

peek
findAny

findFirst

forEach

allMatch

anyMatch
List<Beer> beers = getBeers();

Stream<Beer> beerStream = beers.stream();



beerStream.forEach(b ->System.out.println(b.getName())); //1


beerStream.forEach(b ->System.out.println(b.getAlcohol())); //2
Only use a Stream once
Line 2 will give: 



java.lang.IllegalStateException: stream has already been operated upon or
closed
public Stream<Beer> getMeMyBeers()
public void execute() {
getMeMyBeers() //don’t know if it is consumed yet!!!!
…
}
Don’t return a Stream
Not Consuming a Stream
List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Delirium
Tremens", 9.0), new Beer("Amstel", 5.1));
beers.stream()

.limit(10)

.map(i -> i.getAlcohol())

.peek(i -> {

if (i > 7.0)

throw new RuntimeException();

});
Consume the stream
List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Delirium
Tremens", 9.0), new Beer("Amstel", 5.1));
beers.stream()

.limit(10)

.map(i -> i.getAlcohol())

.peek(i -> {

if (i > 7.0)

throw new RuntimeException();

})
.forEach(System.out::println);
Consume the stream
5.2
Exception in thread "main" java.lang.RuntimeException
Mutable Object
Functional Programming
In computer science, functional programming is a programming
paradigma style of building the structure and elements of computer
programs that treats computation as the evaluation of mathematical
functions and avoids changing-state and mutable data.
It is a declarative programming paradigm, which means programming is
done with expressions or declarations instead of statements.
— wikipedia
– Kevlin Henney
“Asking a question should not
change the answer, nor
should asking it twice”
Immutable objects
Less moving parts
Easier to reason about code
No need to keep a mental map of the state an object is in.
Stream cannot mutate
private final List<Beer> beers = List.of(new Beer("Heineken", 5.2),
new Beer("Amstel", 5.1));
public void execute() {
List<Beer> beersNew = beers.stream()
.map(beer -> beer.setName(“foo”)) //not allowed
.collect(Collectors.toList());
}
Stream should not mutate !
private class Beer {
String name;
Double alcohol;
public Beer setName(String name){
this.name = name;
return this;
}
}
private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel",
5.1));
public void execute() {
List<Beer> beersNew = beers.stream()
.map(beer -> beer.setName("foo"))
.collect(Collectors.toList());
System.out.println(beers);
System.out.println(beersNew);
}
Stream should not mutate !
private class Beer {
String name;
Double alcohol;
public Beer setName(String name){
this.name = name;
return this;
}
}
private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel",
5.1));
public void execute() {
List<Beer> beersNew = beers.stream()
.map(beer -> beer.setName("foo"))
.collect(Collectors.toList());
System.out.println(beers);
System.out.println(beersNew);
}
Return a new copy
private class Beer {
String name;
Double alcohol;
public Beer withName(String name){
return new Beer(name, this.alcohol);
}
}
private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel",
5.1));
public void execute() {
List<Beer> beersNew = beers.stream()
.map(beer -> beer.withName("foo"))
.collect(Collectors.toList());
System.out.println(beers);
System.out.println(beersNew);
}
Overusing forEach
forEach()
Terminal functional on a stream.
Takes a consumer.
Can be used to apply side effects.
for-loop without the external iterator
simple forEach example
List<String> names = List.of("James", "Trisha", "Joshua",
"Jessica","Simon", “Heather”, “Roberto”);
names.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
mutation with forEach
List<Beer> beers = List.of(new Beer("Heineken", 5.2), new
Beer("Amstel", 5.1));
beers.stream()
.forEach(beer -> beer.setAlcohol(0.0));
overusing forEach
private class Beer {
String name;
Double alcohol;
List<String> reviews;
Integer rating;
}
List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1));
//enrich with ratings
beers.stream().forEach(beer -> beer.setRating(findRating(beer.getName())));
//enrich with reviews
beers.stream().forEach(beer -> beer.setReviews(findReviews(beer.getName())));
…
Order of operations
Assignment
Beers -> Brewer -> Country
I want the first 3 unique brewers countries from the beer library as comma separated String
beerLib.stream()
.map(Beer::getBrewer)
.distinct()
.limit(3)
.map(Brewer::getCountry)
.map(String::toUpperCase)
.collect(Collectors.joining(“,”));
Assignment
Beers -> Brewer -> Country
I want the first 3 unique brewers countries from the beer library as comma separated String
beerLib.stream()
.map(Beer::getBrewer)
.distinct()
.limit(3)
.map(Brewer::getCountry)
.map(String::toUpperCase)
.collect(Collectors.joining(“,”));
// wrong
Assignment
Beers -> Brewer -> Country
I want the first 3 unique brewers countries from the beer library as comma separated String
beerLib.stream()
.map(Beer::getBrewer)
.map(Brewer::getCountry)
.map(String::toUpperCase)
.distinct()
.limit(3)
.collect(Collectors.joining(“,”));
// correct
Infinite stream
IntStream.iterate(0, i -> ( i + 1) % 2)

.distinct()

.limit(10)

.forEach(i -> System.out.println(i));
Infinite stream
IntStream.iterate(0, i -> ( i + 1) % 2)

.distinct()

.limit(10)

.forEach(i -> System.out.println(i));

// will run forever
IntStream.iterate(0, i -> ( i + 1) % 2)

.limit(10)

.distinct()

.forEach(i -> System.out.println(i));
//will terminate
Infinite stream
IntStream.iterate(0, i -> ( i + 1) % 2)

.parallel()
.distinct()

.limit(10)

.forEach(i -> System.out.println(i));

// will run forever on all threads.
Solution
1. Look closely at the order of operations

- prevent incorrect answers



2. Only use infinite streams when absolutely necessary.
rather use: 

IntStream.range(0,10);
IntStream.rangeClosed(0,10);
IntStream.iterate(0, i -> i < 10, i -> i + 1); //java 9 and up
Getting an Optional
Optional
Java’s implementation of the Maybe Monad
Encapsulation to handle possible null value
Consider it a wrapper where a value can be absent
Force the user to unpack the Optional before using it.
Optional
Optional<String> c = null //please avoid this
public void execute() {
Optional<String> maybeString = getText();
String unpacked = maybeString.get();
}
Unpack Optional
public void execute() {
Optional<String> maybeString = getText();
String unpacked = maybeString.get();
}
Unpack Optional
NoSuchElementException
public void execute() {
Optional<String> maybeString = getText();
String unpacked = maybeString.get();
}
Unpack Optional
public void execute() {
Optional<String> maybeString = getText();
if (maybeString.isPresent()) {
String unpacked = maybeString.get();
}
}
NoSuchElementException
Unpack Optional
public void execute() {
Optional<String> maybeString = getText();
maybeString.ifPresent( str -> /* doSomething */ );
}
public void execute() {
Optional<String> maybeString = getText();
maybeString.map(str -> str + “.");
}
What else ..??
Alternative flow
- orElse()
- orElseGet()
- orElseThrow()
orElseThrow
public void execute() {

Optional<String> maybeString = Optional.empty();

maybeString

.map(this::runIfExist)

.orElseThrow(() -> new RuntimeException("Optional was empty"));

}
orElse
public void execute() {

Optional<String> maybeString = Optional.of("foo");

String newString = maybeString

.map(this::runIfExist)

.orElse(runIfEmpty());

System.out.println(newString);

}

private String runIfExist(String str) {

System.out.println("only run if optional is filled ");

return str;

}

private String runIfEmpty() {

System.out.println("only run if empty");

return "empty";

}
orElse
public void execute() {

Optional<String> maybeString = Optional.of("foo");

String newString = maybeString

.map(this::runIfExist)

.orElse(runIfEmpty());

System.out.println(newString);

}

private String runIfExist(String str) {

System.out.println("only run if optional is filled ");

return str;

}

private String runIfEmpty() {

System.out.println("only run if empty");

return "empty";

}
only run if optional is filled
only run if empty
foo
orElseGet
public void execute() {

Optional<String> maybeString = Optional.of("foo");

String newString = maybeString

.map(this::runIfExist)

.orElseGet(() -> runIfEmpty());

System.out.println(newString);

}

private String runIfExist(String str) {

System.out.println("only run if optional is filled ");

return str;

}

private String runIfEmpty() {

System.out.println("only run if empty");

return "empty";

}
orElseGet
public void execute() {

Optional<String> maybeString = Optional.of("foo");

String newString = maybeString

.map(this::runIfExist)

.orElseGet(() -> runIfEmpty());

System.out.println(newString);

}

private String runIfExist(String str) {

System.out.println("only run if optional is filled ");

return str;

}

private String runIfEmpty() {

System.out.println("only run if empty");

return "empty";

}
only run if optional is filled
foo
what else?
- When using orElse(x), make sure x doesn’t contain any side effects
- Only use orElse() to assign a default value
- Use orElseGet() to run an alternative flow
Exceptions
Checked Exceptions & Lambda
public Beer doSomething(Beer beer) throws IsEmptyException { …}
Function <Beer,Beer> fBeer = beer -> doSomething(beer)


Checked Exceptions & Lambda
public Beer doSomething(Beer beer) throws IsEmptyException { …}
Function <Beer,Beer> fBeer = beer -> doSomething(beer)


Checked Exceptions & Lambda
public Beer doSomething(Beer beer) throws IsEmptyException { …}
beerLib.stream()
.map(beer -> {

try{

return doSomething(beer);

} catch (IsEmptyException e) {

throw new RuntimeException(e);

}

};)
.collect(Collectors.toList());
//not very pretty
Checked Exceptions & Lambda
public Beer doSomething(Beer beer) throws IsEmptyException { …}
private Beer wrappedDoSomeThing(Beer beer) {

try{

return doSomething(beer);

} catch (IsEmptyException e) {

throw new RuntimeException(e);

}

}
beerLib.stream()
.map(this::wrappedDoSomeThing)
.collect(Collectors.toList());
Exception Utility
@FunctionalInterface

public interface CheckedFunction<T, R> {

public R apply(T t) throws Exception;

}
public static <T, R> Function<T, R> wrap(CheckedFunction<T, R> function) {

return t -> {

try {

return function.apply(t);

} catch (Exception ex) {

throw new RuntimeException(ex);

}

};

};
beerLib.stream()
.map(wrap(beer -> doSomething(beer)))
.collect(Collectors.toList());
Either type
public class Either<L, R> {
private final L left;
private final R right;
private Either(L left, R right) {
this.left = left;
this.right = right;
}
public static <L,R> Either<L,R> Left( L value) {
return new Either(value, null);
}
public static <L,R> Either<L,R> Right( R value) {
return new Either(null, value);
} …
}
Either type
private Either<Exception, String> canGoWrong(Integer input) {
if (input > 10) {
return Either.Left(new RuntimeException("larger then 10"));
}
return Either.Right("["+input+"]");
}
List<Either<Exception, String>> canGoWrongs = IntStream.range(0,12)
.mapToObj(i -> canGoWrong(i))
.collect(Collectors.toList());
Either type
private Either<Exception, String> canGoWrong(Integer input) {
if (input > 10) {
return Either.Left(new RuntimeException("larger then 10"));
}
return Either.Right(“["+input+"]");
}
List<Either<Exception, String>> canGoWrongs = IntStream.range(0,12)
.mapToObj(i -> canGoWrong(i))
.collect(Collectors.toList());
canGoWrongs.stream()
.map(e -> e.mapRight(s -> s.toUpperCase()))
.flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
.forEach(System.out::println);
Try
- Failure (Exception)
- Success (Type)
- VAVR
Try
- Failure (Exception)
- Success (Type)
- VAVR
List<Try<String>> output = teams.stream()
.map(CheckedFunction1.liftTry(this::mayThrowException))
.collect(Collectors.toList());
More with streams
//java 9
List myList = List.of(1,2,3,4,5)
//pre Java9
List myList = Arrays.asList(new String[] {“a”,"b","c"});
Creating collections
//java 9
List myList = List.of(1,2,3,4,5)
//pre Java9
List myList = Arrays.asList(new String[] {"a","b","c"});
// since Java 8
List myList = Stream.of("a","b","c","d").collect(Collectors.toList());
Creating collections
private Beer foo(){...}
private Beer bar(){...}
private Beer fooBar(){…}
Beer myBeer = new Beer();
Beer result = fooBar(bar(foo(myBeer)));
Using Stream.of
private Beer foo(){...}
private Beer bar(){...}
private Beer fooBar(){…}
Beer myBeer = new Beer();
Beer result = fooBar(bar(foo(myBeer)));
Using Stream.of
Beer result = Stream.of(myBeer)
.map(this::foo)

.map(this::bar)

.map(this::fooBar)

.findFirst().get();
String sentence = "The quick fox jumps over the lazy dog. ";
String[] words = sentence
.trim()
.toUpperCase()
.split(" ");
for(String word : words) {
System.out.println(word);
}
Using Stream.of
String sentence = "The quick fox jumps over the lazy dog. ";
String[] words = sentence
.trim()
.toUpperCase()
.split(" ");
for(String word : words) {
System.out.println(word);
}
Stream.of(sentence)
.map(String::trim)
.map(String::toUpperCase)
.map(str -> str.split(" "))
.flatMap(array -> Arrays.stream(array))
.forEach(System.out::println);
Using Stream.of
Brian Vermeer
@BrianVerm
brian@brianvermeer.nl

More Related Content

What's hot

Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
Eueung Mulyana
 
In-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsIn-depth analysis of Kotlin Flows
In-depth analysis of Kotlin Flows
GlobalLogic Ukraine
 
Overpsss API / Overpass-Turbo
Overpsss API / Overpass-TurboOverpsss API / Overpass-Turbo
Overpsss API / Overpass-Turbo
Yu-Chin Tsai
 
Java 8: the good, the bad and the ugly (JBCNConf 2017)
Java 8: the good, the bad and the ugly (JBCNConf 2017)Java 8: the good, the bad and the ugly (JBCNConf 2017)
Java 8: the good, the bad and the ugly (JBCNConf 2017)
Brian Vermeer
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
Ben Scheirman
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
Alessandro Cucci
 
2005_Structures and functions of Makefile
2005_Structures and functions of Makefile2005_Structures and functions of Makefile
2005_Structures and functions of Makefile
NakCheon Jung
 
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Brian Vermeer
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @Silex
Jeen Lee
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
Eueung Mulyana
 
TRunner
TRunnerTRunner
TRunner
Jeen Lee
 
SVN Hook
SVN HookSVN Hook
SVN Hook
Thomas Weinert
 
Filling the flask
Filling the flaskFilling the flask
Filling the flask
Jason Myers
 
Perl one-liners
Perl one-linersPerl one-liners
Perl one-liners
daoswald
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
Lar21
 
LogMiner
LogMinerLogMiner
LogMiner
Anar Godjaev
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the Ugly
Brian Vermeer
 
Debugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo SorochanDebugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo Sorochan
Sphere Consulting Inc
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 

What's hot (19)

Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
 
In-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsIn-depth analysis of Kotlin Flows
In-depth analysis of Kotlin Flows
 
Overpsss API / Overpass-Turbo
Overpsss API / Overpass-TurboOverpsss API / Overpass-Turbo
Overpsss API / Overpass-Turbo
 
Java 8: the good, the bad and the ugly (JBCNConf 2017)
Java 8: the good, the bad and the ugly (JBCNConf 2017)Java 8: the good, the bad and the ugly (JBCNConf 2017)
Java 8: the good, the bad and the ugly (JBCNConf 2017)
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
 
2005_Structures and functions of Makefile
2005_Structures and functions of Makefile2005_Structures and functions of Makefile
2005_Structures and functions of Makefile
 
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
Java 8: the good, the bad and the ugly (Oracle Code Brussels 2017)
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @Silex
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
 
TRunner
TRunnerTRunner
TRunner
 
SVN Hook
SVN HookSVN Hook
SVN Hook
 
Filling the flask
Filling the flaskFilling the flask
Filling the flask
 
Perl one-liners
Perl one-linersPerl one-liners
Perl one-liners
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
 
LogMiner
LogMinerLogMiner
LogMiner
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the Ugly
 
Debugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo SorochanDebugging on Rails. Mykhaylo Sorochan
Debugging on Rails. Mykhaylo Sorochan
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 

Similar to Common mistakes functional java | Oracle Code One 2018

Writing better functional java code devnexus
Writing better functional java code   devnexusWriting better functional java code   devnexus
Writing better functional java code devnexus
Brian Vermeer
 
Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18
Brian Vermeer
 
Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaone
Brian Vermeer
 
こわくないよ❤️ Playframeworkソースコードリーディング入門
こわくないよ❤️ Playframeworkソースコードリーディング入門こわくないよ❤️ Playframeworkソースコードリーディング入門
こわくないよ❤️ Playframeworkソースコードリーディング入門
tanacasino
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Frank Lyaruu
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Aimaf
AimafAimaf
Aimaf
Saad RGUIG
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
JAXLondon_Conference
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
Siarzh Miadzvedzeu
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
Taha Shakeel
 
JDBC Tutorial
JDBC TutorialJDBC Tutorial
JDBC Tutorial
Information Technology
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
Mario Fusco
 
Spring boot
Spring boot Spring boot
Spring boot
Vinay Prajapati
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
Workhorse Computing
 
My java file
My java fileMy java file
My java file
Anamika Chauhan
 
Server Side? Swift
Server Side? SwiftServer Side? Swift
Server Side? Swift
Takaaki Tanaka
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
dantleech
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
Venkata Naga Ravi
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
joaopmaia
 
Web2py Code Lab
Web2py Code LabWeb2py Code Lab
Web2py Code Lab
Colin Su
 

Similar to Common mistakes functional java | Oracle Code One 2018 (20)

Writing better functional java code devnexus
Writing better functional java code   devnexusWriting better functional java code   devnexus
Writing better functional java code devnexus
 
Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18
 
Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaone
 
こわくないよ❤️ Playframeworkソースコードリーディング入門
こわくないよ❤️ Playframeworkソースコードリーディング入門こわくないよ❤️ Playframeworkソースコードリーディング入門
こわくないよ❤️ Playframeworkソースコードリーディング入門
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Aimaf
AimafAimaf
Aimaf
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
JDBC Tutorial
JDBC TutorialJDBC Tutorial
JDBC Tutorial
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Spring boot
Spring boot Spring boot
Spring boot
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
My java file
My java fileMy java file
My java file
 
Server Side? Swift
Server Side? SwiftServer Side? Swift
Server Side? Swift
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Web2py Code Lab
Web2py Code LabWeb2py Code Lab
Web2py Code Lab
 

More from Brian Vermeer

Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022
Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022
Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022
Brian Vermeer
 
Teqnation 19 - Live Hacking
Teqnation 19 - Live Hacking Teqnation 19 - Live Hacking
Teqnation 19 - Live Hacking
Brian Vermeer
 
Don't be a trojan - Codemotion Amsterdam 2019
Don't be a trojan - Codemotion Amsterdam 2019Don't be a trojan - Codemotion Amsterdam 2019
Don't be a trojan - Codemotion Amsterdam 2019
Brian Vermeer
 
Don't be a trojan - Java2Days 2018
Don't be a trojan - Java2Days 2018Don't be a trojan - Java2Days 2018
Don't be a trojan - Java2Days 2018
Brian Vermeer
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
Brian Vermeer
 
Don't be a Trojan
Don't be a TrojanDon't be a Trojan
Don't be a Trojan
Brian Vermeer
 
Identity Theft : Developers are key
Identity Theft : Developers are keyIdentity Theft : Developers are key
Identity Theft : Developers are key
Brian Vermeer
 
Identity theft jfall17
Identity theft jfall17Identity theft jfall17
Identity theft jfall17
Brian Vermeer
 
Identity theft: Developers are key - JavaZone17
Identity theft: Developers are key - JavaZone17Identity theft: Developers are key - JavaZone17
Identity theft: Developers are key - JavaZone17
Brian Vermeer
 
Identity theft blue4it nljug
Identity theft blue4it nljugIdentity theft blue4it nljug
Identity theft blue4it nljug
Brian Vermeer
 
Identity theft: Developers are key - JFokus 2017
Identity theft: Developers are key - JFokus 2017Identity theft: Developers are key - JFokus 2017
Identity theft: Developers are key - JFokus 2017
Brian Vermeer
 

More from Brian Vermeer (11)

Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022
Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022
Stranger Danger: Your Java Attack Surface Just Got Bigger | JBCNConf 2022
 
Teqnation 19 - Live Hacking
Teqnation 19 - Live Hacking Teqnation 19 - Live Hacking
Teqnation 19 - Live Hacking
 
Don't be a trojan - Codemotion Amsterdam 2019
Don't be a trojan - Codemotion Amsterdam 2019Don't be a trojan - Codemotion Amsterdam 2019
Don't be a trojan - Codemotion Amsterdam 2019
 
Don't be a trojan - Java2Days 2018
Don't be a trojan - Java2Days 2018Don't be a trojan - Java2Days 2018
Don't be a trojan - Java2Days 2018
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
 
Don't be a Trojan
Don't be a TrojanDon't be a Trojan
Don't be a Trojan
 
Identity Theft : Developers are key
Identity Theft : Developers are keyIdentity Theft : Developers are key
Identity Theft : Developers are key
 
Identity theft jfall17
Identity theft jfall17Identity theft jfall17
Identity theft jfall17
 
Identity theft: Developers are key - JavaZone17
Identity theft: Developers are key - JavaZone17Identity theft: Developers are key - JavaZone17
Identity theft: Developers are key - JavaZone17
 
Identity theft blue4it nljug
Identity theft blue4it nljugIdentity theft blue4it nljug
Identity theft blue4it nljug
 
Identity theft: Developers are key - JFokus 2017
Identity theft: Developers are key - JFokus 2017Identity theft: Developers are key - JFokus 2017
Identity theft: Developers are key - JFokus 2017
 

Recently uploaded

Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdfRevolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Undress Baby
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
Peter Muessig
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 

Recently uploaded (20)

Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdfRevolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 

Common mistakes functional java | Oracle Code One 2018

  • 1. Common mistakes made with Functional Java Brian Vermeer (@BrianVerm)
  • 2.
  • 3.
  • 4.
  • 6. Doing too much in a single lambda
  • 7. Lambda Expression In computer programming, a lambda expression is a function definition that is not bound to an identifier. Anonymous functions are often:[1] • arguments being passed to higher-order functions, or • used for constructing the result of a higher-order function that needs to return a function.
  • 8. Lambda in Java Anonymous Inner functions Satisfy a Functional Interface They only exist in runtime Single Line <input> -> <output> or Block <input> -> { function body }
  • 9. Example public void execute() { Beer grolsch = new Beer("Grolsche", 4.3); String result = handleBeer(grolsch, beer -> grolsch.getName() + "-" + grolsch.getAlcohol()); System.out.println(result); } private String handleBeer(Beer beer, Function<Beer, String> func) { System.out.println("handling beer " + beer.getName()); return func.apply(beer); } //Output : Grolsche-4.3
  • 10. Example public void execute() { Beer grolsch = new Beer("Grolsche", 4.3); String result = handleBeer(grolsch, beer -> grolsch.getName() + "-" + grolsch.getAlcohol()); System.out.println(result); } private String handleBeer(Beer beer, Function<Beer, String> func) { System.out.println("handling beer " + beer.getName()); return func.apply(beer); } //Output : Grolsche-4.3
  • 11. Don’t do Block Lambda beer -> { String name; if (beer.getName().contains(" ")) { name = beer.getName().replace(" ", ""); } else { name = beer.getName(); } try { name += Integer.parseInt(beer.getAlcoholPrecentage().toString()); } catch (NumberFormatException nfe) { name += beer.getAlcoholPrecentage(); } return name; }
  • 12. Transform to a methode private String createFullName (Beer beer){ String name; if (beer.getName().contains(" ")) { name = beer.getName().replace(" ", ""); } else { name = beer.getName(); } try { name += Integer.parseInt(beer.getAlcoholPrecentage().toString()); } catch (NumberFormatException nfe) { name += beer.getAlcoholPrecentage(); } return name; } handleBeer(grolsch, this::createFullName);
  • 14. A stream is NOT a data structure
  • 15. A stream is NOT a data structure A stream is NOT a data structure
  • 16. What is Stream ( in Java) Flow of data derived from a Collection Can create a pipeline of function that can be evaluated Intermediate result Lazy evaluated by nature Can transform data, cannot mutate data
  • 17. JAVA Streams stringLists.stream()
 .map(str -> str.toUpperCase())
 .collect(Collectors.toList()); Intermediate filter 
 distinct
 map 
 flatMap
 Terminal reduce
 collect
 toArray
 count
 max
 min
 limit 
 skip
 sorted
 peek findAny
 findFirst
 forEach
 allMatch
 anyMatch
  • 18. List<Beer> beers = getBeers();
 Stream<Beer> beerStream = beers.stream();
 
 beerStream.forEach(b ->System.out.println(b.getName())); //1 
 beerStream.forEach(b ->System.out.println(b.getAlcohol())); //2 Only use a Stream once Line 2 will give: 
 
 java.lang.IllegalStateException: stream has already been operated upon or closed
  • 19. public Stream<Beer> getMeMyBeers() public void execute() { getMeMyBeers() //don’t know if it is consumed yet!!!! … } Don’t return a Stream
  • 20. Not Consuming a Stream
  • 21.
  • 22.
  • 23.
  • 24.
  • 25. List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Delirium Tremens", 9.0), new Beer("Amstel", 5.1)); beers.stream()
 .limit(10)
 .map(i -> i.getAlcohol())
 .peek(i -> {
 if (i > 7.0)
 throw new RuntimeException();
 }); Consume the stream
  • 26.
  • 27. List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Delirium Tremens", 9.0), new Beer("Amstel", 5.1)); beers.stream()
 .limit(10)
 .map(i -> i.getAlcohol())
 .peek(i -> {
 if (i > 7.0)
 throw new RuntimeException();
 }) .forEach(System.out::println); Consume the stream 5.2 Exception in thread "main" java.lang.RuntimeException
  • 29. Functional Programming In computer science, functional programming is a programming paradigma style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements. — wikipedia
  • 30.
  • 31. – Kevlin Henney “Asking a question should not change the answer, nor should asking it twice”
  • 32. Immutable objects Less moving parts Easier to reason about code No need to keep a mental map of the state an object is in.
  • 33. Stream cannot mutate private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1)); public void execute() { List<Beer> beersNew = beers.stream() .map(beer -> beer.setName(“foo”)) //not allowed .collect(Collectors.toList()); }
  • 34. Stream should not mutate ! private class Beer { String name; Double alcohol; public Beer setName(String name){ this.name = name; return this; } } private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1)); public void execute() { List<Beer> beersNew = beers.stream() .map(beer -> beer.setName("foo")) .collect(Collectors.toList()); System.out.println(beers); System.out.println(beersNew); }
  • 35. Stream should not mutate ! private class Beer { String name; Double alcohol; public Beer setName(String name){ this.name = name; return this; } } private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1)); public void execute() { List<Beer> beersNew = beers.stream() .map(beer -> beer.setName("foo")) .collect(Collectors.toList()); System.out.println(beers); System.out.println(beersNew); }
  • 36. Return a new copy private class Beer { String name; Double alcohol; public Beer withName(String name){ return new Beer(name, this.alcohol); } } private final List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1)); public void execute() { List<Beer> beersNew = beers.stream() .map(beer -> beer.withName("foo")) .collect(Collectors.toList()); System.out.println(beers); System.out.println(beersNew); }
  • 38. forEach() Terminal functional on a stream. Takes a consumer. Can be used to apply side effects. for-loop without the external iterator
  • 39. simple forEach example List<String> names = List.of("James", "Trisha", "Joshua", "Jessica","Simon", “Heather”, “Roberto”); names.stream() .map(String::toUpperCase) .forEach(System.out::println);
  • 40. mutation with forEach List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1)); beers.stream() .forEach(beer -> beer.setAlcohol(0.0));
  • 41. overusing forEach private class Beer { String name; Double alcohol; List<String> reviews; Integer rating; } List<Beer> beers = List.of(new Beer("Heineken", 5.2), new Beer("Amstel", 5.1)); //enrich with ratings beers.stream().forEach(beer -> beer.setRating(findRating(beer.getName()))); //enrich with reviews beers.stream().forEach(beer -> beer.setReviews(findReviews(beer.getName()))); …
  • 43. Assignment Beers -> Brewer -> Country I want the first 3 unique brewers countries from the beer library as comma separated String beerLib.stream() .map(Beer::getBrewer) .distinct() .limit(3) .map(Brewer::getCountry) .map(String::toUpperCase) .collect(Collectors.joining(“,”));
  • 44. Assignment Beers -> Brewer -> Country I want the first 3 unique brewers countries from the beer library as comma separated String beerLib.stream() .map(Beer::getBrewer) .distinct() .limit(3) .map(Brewer::getCountry) .map(String::toUpperCase) .collect(Collectors.joining(“,”)); // wrong
  • 45. Assignment Beers -> Brewer -> Country I want the first 3 unique brewers countries from the beer library as comma separated String beerLib.stream() .map(Beer::getBrewer) .map(Brewer::getCountry) .map(String::toUpperCase) .distinct() .limit(3) .collect(Collectors.joining(“,”)); // correct
  • 46. Infinite stream IntStream.iterate(0, i -> ( i + 1) % 2)
 .distinct()
 .limit(10)
 .forEach(i -> System.out.println(i));
  • 47. Infinite stream IntStream.iterate(0, i -> ( i + 1) % 2)
 .distinct()
 .limit(10)
 .forEach(i -> System.out.println(i));
 // will run forever IntStream.iterate(0, i -> ( i + 1) % 2)
 .limit(10)
 .distinct()
 .forEach(i -> System.out.println(i)); //will terminate
  • 48. Infinite stream IntStream.iterate(0, i -> ( i + 1) % 2)
 .parallel() .distinct()
 .limit(10)
 .forEach(i -> System.out.println(i));
 // will run forever on all threads.
  • 49. Solution 1. Look closely at the order of operations
 - prevent incorrect answers
 
 2. Only use infinite streams when absolutely necessary. rather use: 
 IntStream.range(0,10); IntStream.rangeClosed(0,10); IntStream.iterate(0, i -> i < 10, i -> i + 1); //java 9 and up
  • 51. Optional Java’s implementation of the Maybe Monad Encapsulation to handle possible null value Consider it a wrapper where a value can be absent Force the user to unpack the Optional before using it.
  • 52. Optional Optional<String> c = null //please avoid this
  • 53. public void execute() { Optional<String> maybeString = getText(); String unpacked = maybeString.get(); } Unpack Optional
  • 54. public void execute() { Optional<String> maybeString = getText(); String unpacked = maybeString.get(); } Unpack Optional NoSuchElementException
  • 55. public void execute() { Optional<String> maybeString = getText(); String unpacked = maybeString.get(); } Unpack Optional public void execute() { Optional<String> maybeString = getText(); if (maybeString.isPresent()) { String unpacked = maybeString.get(); } } NoSuchElementException
  • 56. Unpack Optional public void execute() { Optional<String> maybeString = getText(); maybeString.ifPresent( str -> /* doSomething */ ); } public void execute() { Optional<String> maybeString = getText(); maybeString.map(str -> str + “."); }
  • 58. Alternative flow - orElse() - orElseGet() - orElseThrow()
  • 59. orElseThrow public void execute() {
 Optional<String> maybeString = Optional.empty();
 maybeString
 .map(this::runIfExist)
 .orElseThrow(() -> new RuntimeException("Optional was empty"));
 }
  • 60. orElse public void execute() {
 Optional<String> maybeString = Optional.of("foo");
 String newString = maybeString
 .map(this::runIfExist)
 .orElse(runIfEmpty());
 System.out.println(newString);
 }
 private String runIfExist(String str) {
 System.out.println("only run if optional is filled ");
 return str;
 }
 private String runIfEmpty() {
 System.out.println("only run if empty");
 return "empty";
 }
  • 61. orElse public void execute() {
 Optional<String> maybeString = Optional.of("foo");
 String newString = maybeString
 .map(this::runIfExist)
 .orElse(runIfEmpty());
 System.out.println(newString);
 }
 private String runIfExist(String str) {
 System.out.println("only run if optional is filled ");
 return str;
 }
 private String runIfEmpty() {
 System.out.println("only run if empty");
 return "empty";
 } only run if optional is filled only run if empty foo
  • 62. orElseGet public void execute() {
 Optional<String> maybeString = Optional.of("foo");
 String newString = maybeString
 .map(this::runIfExist)
 .orElseGet(() -> runIfEmpty());
 System.out.println(newString);
 }
 private String runIfExist(String str) {
 System.out.println("only run if optional is filled ");
 return str;
 }
 private String runIfEmpty() {
 System.out.println("only run if empty");
 return "empty";
 }
  • 63. orElseGet public void execute() {
 Optional<String> maybeString = Optional.of("foo");
 String newString = maybeString
 .map(this::runIfExist)
 .orElseGet(() -> runIfEmpty());
 System.out.println(newString);
 }
 private String runIfExist(String str) {
 System.out.println("only run if optional is filled ");
 return str;
 }
 private String runIfEmpty() {
 System.out.println("only run if empty");
 return "empty";
 } only run if optional is filled foo
  • 64. what else? - When using orElse(x), make sure x doesn’t contain any side effects - Only use orElse() to assign a default value - Use orElseGet() to run an alternative flow
  • 66. Checked Exceptions & Lambda public Beer doSomething(Beer beer) throws IsEmptyException { …} Function <Beer,Beer> fBeer = beer -> doSomething(beer) 

  • 67. Checked Exceptions & Lambda public Beer doSomething(Beer beer) throws IsEmptyException { …} Function <Beer,Beer> fBeer = beer -> doSomething(beer) 

  • 68. Checked Exceptions & Lambda public Beer doSomething(Beer beer) throws IsEmptyException { …} beerLib.stream() .map(beer -> {
 try{
 return doSomething(beer);
 } catch (IsEmptyException e) {
 throw new RuntimeException(e);
 }
 };) .collect(Collectors.toList()); //not very pretty
  • 69. Checked Exceptions & Lambda public Beer doSomething(Beer beer) throws IsEmptyException { …} private Beer wrappedDoSomeThing(Beer beer) {
 try{
 return doSomething(beer);
 } catch (IsEmptyException e) {
 throw new RuntimeException(e);
 }
 } beerLib.stream() .map(this::wrappedDoSomeThing) .collect(Collectors.toList());
  • 70. Exception Utility @FunctionalInterface
 public interface CheckedFunction<T, R> {
 public R apply(T t) throws Exception;
 } public static <T, R> Function<T, R> wrap(CheckedFunction<T, R> function) {
 return t -> {
 try {
 return function.apply(t);
 } catch (Exception ex) {
 throw new RuntimeException(ex);
 }
 };
 }; beerLib.stream() .map(wrap(beer -> doSomething(beer))) .collect(Collectors.toList());
  • 71. Either type public class Either<L, R> { private final L left; private final R right; private Either(L left, R right) { this.left = left; this.right = right; } public static <L,R> Either<L,R> Left( L value) { return new Either(value, null); } public static <L,R> Either<L,R> Right( R value) { return new Either(null, value); } … }
  • 72. Either type private Either<Exception, String> canGoWrong(Integer input) { if (input > 10) { return Either.Left(new RuntimeException("larger then 10")); } return Either.Right("["+input+"]"); } List<Either<Exception, String>> canGoWrongs = IntStream.range(0,12) .mapToObj(i -> canGoWrong(i)) .collect(Collectors.toList());
  • 73. Either type private Either<Exception, String> canGoWrong(Integer input) { if (input > 10) { return Either.Left(new RuntimeException("larger then 10")); } return Either.Right(“["+input+"]"); } List<Either<Exception, String>> canGoWrongs = IntStream.range(0,12) .mapToObj(i -> canGoWrong(i)) .collect(Collectors.toList()); canGoWrongs.stream() .map(e -> e.mapRight(s -> s.toUpperCase())) .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) .forEach(System.out::println);
  • 74. Try - Failure (Exception) - Success (Type) - VAVR
  • 75. Try - Failure (Exception) - Success (Type) - VAVR List<Try<String>> output = teams.stream() .map(CheckedFunction1.liftTry(this::mayThrowException)) .collect(Collectors.toList());
  • 77. //java 9 List myList = List.of(1,2,3,4,5) //pre Java9 List myList = Arrays.asList(new String[] {“a”,"b","c"}); Creating collections
  • 78. //java 9 List myList = List.of(1,2,3,4,5) //pre Java9 List myList = Arrays.asList(new String[] {"a","b","c"}); // since Java 8 List myList = Stream.of("a","b","c","d").collect(Collectors.toList()); Creating collections
  • 79. private Beer foo(){...} private Beer bar(){...} private Beer fooBar(){…} Beer myBeer = new Beer(); Beer result = fooBar(bar(foo(myBeer))); Using Stream.of
  • 80. private Beer foo(){...} private Beer bar(){...} private Beer fooBar(){…} Beer myBeer = new Beer(); Beer result = fooBar(bar(foo(myBeer))); Using Stream.of Beer result = Stream.of(myBeer) .map(this::foo)
 .map(this::bar)
 .map(this::fooBar)
 .findFirst().get();
  • 81. String sentence = "The quick fox jumps over the lazy dog. "; String[] words = sentence .trim() .toUpperCase() .split(" "); for(String word : words) { System.out.println(word); } Using Stream.of
  • 82. String sentence = "The quick fox jumps over the lazy dog. "; String[] words = sentence .trim() .toUpperCase() .split(" "); for(String word : words) { System.out.println(word); } Stream.of(sentence) .map(String::trim) .map(String::toUpperCase) .map(str -> str.split(" ")) .flatMap(array -> Arrays.stream(array)) .forEach(System.out::println); Using Stream.of