SlideShare una empresa de Scribd logo
1 de 83
Descargar para leer sin conexión
Ten common mistakes

made with Functional Java
Brian Vermeer
@BrianVerm brian@brianvermeer.nl #devsum18
Ten 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");
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 Throwable;

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

return t -> {

try {

return function.apply(t);

} catch (Throwable ex) {

throw new RuntimeException(ex);

}

};

};
beerLib.stream()
.map(beer -> wrap(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);
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
Don’t forget to evaluate 

this session in the DevSum app!
Brian Vermeer
@BrianVerm
brian@brianvermeer.nl

Más contenido relacionado

La actualidad más candente

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
 
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
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyAlessandro Cucci
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthEueung Mulyana
 
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 UglyBrian Vermeer
 
In-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsIn-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsGlobalLogic Ukraine
 
How to export import a mysql database via ssh in aws lightsail wordpress rizw...
How to export import a mysql database via ssh in aws lightsail wordpress rizw...How to export import a mysql database via ssh in aws lightsail wordpress rizw...
How to export import a mysql database via ssh in aws lightsail wordpress rizw...AlexRobert25
 
Endevor api an introduction to the endevor application programming interface
Endevor api   an introduction to the endevor application programming interface Endevor api   an introduction to the endevor application programming interface
Endevor api an introduction to the endevor application programming interface Kevin Grimes
 
Filling the flask
Filling the flaskFilling the flask
Filling the flaskJason Myers
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @SilexJeen Lee
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Lar21
 
Flask patterns
Flask patternsFlask patterns
Flask patternsit-people
 
Apache cheat sheet
Apache cheat sheetApache cheat sheet
Apache cheat sheetLam Hoang
 
Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8Rupesh Kumar
 

La actualidad más candente (19)

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)
 
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)
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
 
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
 
In-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsIn-depth analysis of Kotlin Flows
In-depth analysis of Kotlin Flows
 
How to export import a mysql database via ssh in aws lightsail wordpress rizw...
How to export import a mysql database via ssh in aws lightsail wordpress rizw...How to export import a mysql database via ssh in aws lightsail wordpress rizw...
How to export import a mysql database via ssh in aws lightsail wordpress rizw...
 
Endevor api an introduction to the endevor application programming interface
Endevor api   an introduction to the endevor application programming interface Endevor api   an introduction to the endevor application programming interface
Endevor api an introduction to the endevor application programming interface
 
Filling the flask
Filling the flaskFilling the flask
Filling the flask
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @Silex
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
 
Flask patterns
Flask patternsFlask patterns
Flask patterns
 
Apache cheat sheet
Apache cheat sheetApache cheat sheet
Apache cheat sheet
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
SVN Hook
SVN HookSVN Hook
SVN Hook
 
TRunner
TRunnerTRunner
TRunner
 
Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8
 

Similar a Top 10 mistakes with Functional Java

Writing better functional java code devnexus
Writing better functional java code   devnexusWriting better functional java code   devnexus
Writing better functional java code devnexusBrian Vermeer
 
Ten common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitTen common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitBrian Vermeer
 
Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18Brian Vermeer
 
Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaoneBrian 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 RxJavaFrank Lyaruu
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniquesjoaopmaia
 
Simplifying java with lambdas (short)
Simplifying java with lambdas (short)Simplifying java with lambdas (short)
Simplifying java with lambdas (short)RichardWarburton
 
30 5 Database Jdbc
30 5 Database Jdbc30 5 Database Jdbc
30 5 Database Jdbcphanleson
 
GeeCON 2014 - Functional Programming without Lambdas
GeeCON 2014 - Functional Programming without LambdasGeeCON 2014 - Functional Programming without Lambdas
GeeCON 2014 - Functional Programming without LambdasMattias Severson
 

Similar a Top 10 mistakes with Functional Java (20)

Writing better functional java code devnexus
Writing better functional java code   devnexusWriting better functional java code   devnexus
Writing better functional java code devnexus
 
Ten common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitTen common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java Summit
 
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ソースコードリーディング入門
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Sailing with Java 8 Streams
Sailing with Java 8 StreamsSailing with Java 8 Streams
Sailing with Java 8 Streams
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
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
 
Spring boot
Spring boot Spring boot
Spring boot
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
JDBC Tutorial
JDBC TutorialJDBC Tutorial
JDBC Tutorial
 
Java
JavaJava
Java
 
Aimaf
AimafAimaf
Aimaf
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Simplifying java with lambdas (short)
Simplifying java with lambdas (short)Simplifying java with lambdas (short)
Simplifying java with lambdas (short)
 
Server Side? Swift
Server Side? SwiftServer Side? Swift
Server Side? Swift
 
30 5 Database Jdbc
30 5 Database Jdbc30 5 Database Jdbc
30 5 Database Jdbc
 
GeeCON 2014 - Functional Programming without Lambdas
GeeCON 2014 - Functional Programming without LambdasGeeCON 2014 - Functional Programming without Lambdas
GeeCON 2014 - Functional Programming without Lambdas
 

Más de 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 2022Brian 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 2019Brian 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 2018Brian Vermeer
 
Identity Theft : Developers are key
Identity Theft : Developers are keyIdentity Theft : Developers are key
Identity Theft : Developers are keyBrian Vermeer
 
Identity theft jfall17
Identity theft jfall17Identity theft jfall17
Identity theft jfall17Brian Vermeer
 
Identity theft: Developers are key - JavaZone17
Identity theft: Developers are key - JavaZone17Identity theft: Developers are key - JavaZone17
Identity theft: Developers are key - JavaZone17Brian Vermeer
 
Identity theft blue4it nljug
Identity theft blue4it nljugIdentity theft blue4it nljug
Identity theft blue4it nljugBrian 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 2017Brian Vermeer
 

Más de Brian Vermeer (10)

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
 
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
 

Último

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 

Último (20)

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 

Top 10 mistakes with Functional Java

  • 1. Ten common mistakes
 made with Functional Java Brian Vermeer @BrianVerm brian@brianvermeer.nl #devsum18
  • 2. Ten common mistakes made with Functional Java Brian Vermeer (@BrianVerm)
  • 3.
  • 4.
  • 5.
  • 7. Doing too much in a single lambda
  • 8. 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.
  • 9. Lambda in Java Anonymous Inner functions Satisfy a Functional Interface They only exist in runtime Single Line <input> -> <output> or Block <input> -> { function body }
  • 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. 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
  • 12. 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; }
  • 13. 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);
  • 15. A stream is NOT a data structure
  • 16. A stream is NOT a data structure A stream is NOT a data structure
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. public Stream<Beer> getMeMyBeers() public void execute() { getMeMyBeers() //don’t know if it is consumed yet!!!! … } Don’t return a Stream
  • 21. Not Consuming a Stream
  • 22.
  • 23.
  • 24.
  • 25.
  • 26. 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
  • 27.
  • 28. 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
  • 30. 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
  • 31.
  • 32. – Kevlin Henney “Asking a question should not change the answer, nor should asking it twice”
  • 33. Immutable objects Less moving parts Easier to reason about code No need to keep a mental map of the state an object is in.
  • 34. 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()); }
  • 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. 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); }
  • 37. 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); }
  • 39. forEach() Terminal functional on a stream. Takes a consumer. Can be used to apply side effects. for-loop without the external iterator
  • 40. simple forEach example List<String> names = List.of("James", "Trisha", "Joshua", "Jessica","Simon", “Heather"); names.stream() .map(String::toUpperCase) .forEach(System.out::println);
  • 41. 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));
  • 42. 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()))); …
  • 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(“,”));
  • 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) .distinct() .limit(3) .map(Brewer::getCountry) .map(String::toUpperCase) .collect(Collectors.joining(“,”)); // wrong
  • 46. 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
  • 47. Infinite stream IntStream.iterate(0, i -> ( i + 1) % 2)
 .distinct()
 .limit(10)
 .forEach(i -> System.out.println(i));
  • 48. 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
  • 49. 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.
  • 50. 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
  • 52. 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.
  • 53. Optional Optional<String> c = null //please avoid this
  • 54. public void execute() { Optional<String> maybeString = getText(); String unpacked = maybeString.get(); } Unpack Optional
  • 55. public void execute() { Optional<String> maybeString = getText(); String unpacked = maybeString.get(); } Unpack Optional NoSuchElementException
  • 56. 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
  • 57. Unpack Optional public void execute() { Optional<String> maybeString = getText(); maybeString.ifPresent( str -> /* doSomething */ ); } public void execute() { Optional<String> maybeString = getText(); maybeString.map(str -> str + “."); }
  • 59. Alternative flow - orElse() - orElseGet() - orElseThrow()
  • 60. orElseThrow public void execute() {
 Optional<String> maybeString = Optional.empty();
 maybeString
 .map(this::runIfExist)
 .orElseThrow(() -> new RuntimeException("Optional was 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";
 }
  • 62. 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
  • 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";
 }
  • 64. 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
  • 65. 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
  • 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 { …} Function <Beer,Beer> fBeer = beer -> doSomething(beer) 

  • 69. 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
  • 70. 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());
  • 71. Exception Utility @FunctionalInterface
 public interface CheckedFunction<T, R> {
 public R apply(T t) throws Throwable;
 } public static <T, R> Function<T, R> wrap(CheckedFunction<T, R> function) {
 return t -> {
 try {
 return function.apply(t);
 } catch (Throwable ex) {
 throw new RuntimeException(ex);
 }
 };
 }; beerLib.stream() .map(beer -> wrap(doSomething(beer))) .collect(Collectors.toList());
  • 72. 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); } … }
  • 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());
  • 74. 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);
  • 76. //java 9 List myList = List.of(1,2,3,4,5) //pre Java9 List myList = Arrays.asList(new String[] {“a”,"b","c"}); Creating collections
  • 77. //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
  • 78. private Beer foo(){...} private Beer bar(){...} private Beer fooBar(){…} Beer myBeer = new Beer(); Beer result = fooBar(bar(foo(myBeer))); Using Stream.of
  • 79. 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();
  • 80. 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
  • 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); } 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
  • 82. Don’t forget to evaluate 
 this session in the DevSum app!