SlideShare a Scribd company logo
Java 8 and .
1
javaBin Oslo – 12.05.2015
Fredrik Vraalsen
fredriv vraalsen@iterate.no
2
Java 8 – what’s new?
Lambdas
Method handles
Extension methods
Streams
Optional
3
Java 8 – what’s new?
Lambdas (anonymous functions)
Method handles
Extension methods
Streams
Optional
4
5
Java 7 vs 8
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getName().compareTo(y.getName());
}
});
6
Java 7 vs 8
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getName().compareTo(y.getName());
}
});
vs
sort(people, (x, y) -> x.getName().compareTo(y.getName()));
7
Java 7 vs 8
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getName().compareTo(y.getName());
}
});
vs
sort(people, comparing(person -> person.getName()));
8
Java 7 vs 8
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getName().compareTo(y.getName());
}
});
vs
sort(people, comparing(Person::getName));
9
Java 7 vs 8
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getName().compareTo(y.getName());
}
});
vs
people.sort(comparing(Person::getName));
10
Streams
© Fredrik Vraalsen 2008
Old fashioned imperative
12
List<RoadData> filtered = new ArrayList<>();
int count = 0;
for (Iterator<RoadData> i = roadData.iterator();
i.hasNext() && count < 10; ) {
RoadData data = i.next();
if (nameQuery.matches(data.getName())) {
filtered.add(data);
count++;
}
}
Streams
13
roadData.stream()
.filter(data -> nameQuery.matches(data.getName()))
.limit(10)
.collect(toList());
Streams – pipelines
14
roadData.stream()
.filter(data -> nameQuery.matches(data.getName()))
.limit(10)
.collect(toList());
cat roadData.txt | grep … | head > output.txt
Learn you a Stream API
15
Map<String, List<Article>> articlesByCategory =
Learn you a Stream API
16
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
Learn you a Stream API
17
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(transport -> convertToArticle(transport))
Learn you a Stream API
18
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(transport -> convertToArticle(transport))
.collect(groupingBy(article -> article.getCategory()));
Learn you a Stream API
19
Method handles
20
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(transport -> convertToArticle(transport))
.collect(groupingBy(article -> article.getCategory()));
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(this::convertToArticle)
.collect(groupingBy(article -> article.getCategory()));
Method handles
21
Method handles
22
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(this::convertToArticle)
.collect(groupingBy(Article::getCategory));
Naming, caching, counting
23
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(this::convertToArticle)
.collect(groupingBy(Article::getCategory));
Naming, caching, counting
24
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(this::transportToArticle)
.collect(groupingBy(Article::category));
Extract functions
25
Map<String, List<Article>> articlesByCategory =
articleTransports.stream()
.map(transportToArticle)
.collect(groupingBy(Article::category));
Function<ArticleTransport, Article> transportToArticle =
transport -> convertToArticle(transport);
Lambdas everywhere!!!1!
links.stream()
.map(link -> link.build())
.forEach(abderaElement::addLink);
26
Old school ifs and fors
links.stream()
.map(link -> link.build())
.forEach(abderaElement::addLink);
for (LinkBuilder lb : links) {

abderaElement.addLink(lb.build());

}
27
Parsing nested JSON
"suggest": {
"tag_suggest": [
{
"length": 5,
"offset": 0,
"options": [
{
"freq": 25,
"score": 0.8,
"text": "fakta"
}
],
"text": "fanta"
}
]
} 28
Lambdas everywhere!!!1!
List<String> terms = new ArrayList<>();

suggestions.getAsJsonObject().getAsJsonArray(“tag_suggest”)

.forEach(tag -> tag.getAsJsonObject().getAsJsonArray("options")

.forEach(option -> terms

.add(option.getAsJsonObject().getAsJsonPrimitive("text")

.getAsString())));

29
Old school ifs and fors
List<String> terms = new ArrayList<>();

for (JsonElement tag : suggestions.getAsJsonObject().getAsJsonArray("tag_suggest")) {

for (JsonElement option : tag.getAsJsonObject().getAsJsonArray("options")) {

terms.add(option.getAsJsonObject().getAsJsonPrimitive("text").getAsString());

}

}

30
Old school ifs and fors
List<String> terms = new ArrayList<>();

for (JsonElement tag : getAll("tag_suggest", suggestions)) {

for (JsonElement option : getAll("options", tag)) {

terms.add(getString("text", option));

}

}

31
List<String> terms = getAll("tag_suggest", suggestions).stream()

.flatMap(tag -> getAll("options", tag).stream())

.map(option -> getString("text", option))

.collect(Collectors.toList());
32
Lambdas everywhere!!!1!
Readability ≫ Style / LOC
Always code as if the person who ends up maintaining your code
is a violent psychopath who knows where you live.
http://c2.com/cgi/wiki?CodeForTheMaintainer
OH NOES
NullPointerException!!?!
© Fredrik Vraalsen 201
Optional<T>
Wrapper object
Make explicit if a value is present or absent (empty)
35
Optional example
public Optional<Image> getImage(Article article)
---
36
Optional example
public Optional<Image> getImage(Article article)
---
Optional<Image> image = getImage(article);
37
Check presence
public Optional<Image> getImage(Article article)
---
Optional<Image> image = getImage(article);
if (image.isPresent()) {
doSomething(image.get());
}
38
Check presence
public Optional<Image> getImage(Article article)
---
Optional<Image> image = getImage(article);
image.ifPresent(img -> doSomething(img));
39
Check presence
public Optional<Image> getImage(Article article)
---
getImage(article).ifPresent(image -> doSomething(image));
40
Default / fallback value
public Optional<Image> getImage(Article article)
---
Image image = getImage(article).orElse(defaultImage);
41
Optional in / Optional out
public Optional<String> getCaption(Optional<Image> image)
---
Optional<Image> image = getImage(article);
Optional<String> caption = getCaption(image);
42
Optional in / Optional out
public String getCaption(Image image)
---
Optional<Image> image = getImage(article);
Optional<String> caption = ???
43
Reaching into the void …
public String getCaption(Image image)
---
Optional<Image> image = getImage(article);
Optional<String> caption = image.map(img -> getCaption(img));
44
Reaching into the void …
public String getCaption(Image image)
---
Optional<String> caption = getImage(article)
.map(img -> getCaption(image));
45
Bye bye NullPointerException?
Marker – this may not return/contain value
Public APIs
Not a general solution to NPEs
46
Optional + Streams = true?
47
Optional + Streams = true?
48
myStream.map(v -> functionReturningOptional(v))
Optional + Streams = true?
49
myStream.map(v -> functionReturningOptional(v))
Stream<Optional<T>>
Optional + Streams = true?
50
myStream.map(v -> functionReturningOptional(v))
Stream<Optional<T>> Stream<T> ???
Guava Optional
51
Iterable<T> presentInstances(Iterable<Optional<T>> optionals)
Optional + Streams = true?
52
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>
Optional + Streams = true?
53
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.map(article -> getImage(article)) // Stream<Optional<Image>>
Optional + Streams = true?
54
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.map(article -> getImage(article)) // Stream<Optional<Image>>
.filter(Optional::ifPresent)
.map(Optional::get) // Stream<Image>

Optional + Streams = true?
55
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.map(article -> getImage(article)) // Stream<Optional<Image>>
.filter(Optional::ifPresent)
.map(Optional::get) // Stream<Image>

.collect(toList());
flatMap to the rescue!
flatMap = map + flatten
Stream<Stream<T>> Stream<T>
56
flatMap to the rescue!
flatMap = map + flatten
Stream<Optional<T>> Stream<T> ???
57
flatMap to the rescue!
Easy to create helper functions
Stream<T> toStream(Optional<T> optValue)
58
http://stackoverflow.com/questions/22725537/using-java-8s-optional-with-streamflatmap
Optional + Streams = true?
59
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.map(article -> getImage(article)) // Stream<Optional<Image>>
.filter(Optional::ifPresent)
.map(Optional::get) // Stream<Image>

.collect(toList());
Optional + Streams = true
60
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.flatMap(article -> toStream(getImage(article))) // Stream<Image>

.collect(toList());
Optional + Streams = true
61
public Optional<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.flatMap(article -> getImage(article).stream()) // Stream<Image>

.collect(toList());
Java 9
https://bugs.openjdk.java.net/browse/JDK-8050820
Take one stream and pass it around…
62
public Stream<Image> getImage(Article article)
---
List<Image> images = articles.stream() // Stream<Article>

.flatMap(article -> getImage(article)) // Stream<Image>

.collect(toList());
No method handle for you!
63
private Article elementToArticle(Map contentById, Element el)
---
List<Article> articles = elements.stream()

.map(el -> elementToArticle(contentById, el))

.collect(toList())
64
http://en.wikipedia.org/wiki/Malabar_matthi_curry#/media/File:Meen_curry_2_(cropped).JPG
Yummy currying!!
65
Mapper mapper = new Mapper(contentById);
---
List<Article> articles = elements.stream()

.map(el -> mapper.elementToArticle(el))

.collect(toList())
Yummy currying!!
66
Mapper mapper = new Mapper(contentById);
---
List<Article> articles = elements.stream()

.map(mapper::elementToArticle)

.collect(toList())
Performance
© Fredrik Vraalsen 2012
Streams – performance
List<Article> frontpageArticles =
frontpage.getArticleIds().stream()
.map(id -> fetchArticle(id))
.collect(toList());
68
This one goes to 11!
List<Article> frontpageArticles =
frontpage.getArticleIds().parallelStream()
.map(id -> fetchArticle(id))
.collect(toList());
69
Starvation
Common F/J thread pool
Workarounds?
Execute within explicit F/J pool
Use CompletableFuture
70
CompletableFuture
Chaining of async futures and actions
Waiting for all or any future(s)
Explicitly complete (like Promise)
Control of executor service
71
http://blog.krecan.net/2014/03/18/how-to-specify-thread-pool-for-java-8-parallel-streams/
http://www.nurkiewicz.com/2013/05/java-8-completablefuture-in-action.html
To parallelStream or not to …
Batch?
parallelStream FTW!
Interactive? Concurrency?
CompletableFuture FTW!
72
Taking the happy path!
Try<RestResponse<ResolvedUri>> resolveURI(URI uri)
---
public ResolvedSectionUri resolveSectionUri(String uri) {
return client.resolveURI(uri))
??? Try<RestResponse<ResolvedUri>>

}
73
Taking the happy path!
Try<RestResponse<ResolvedUri>> resolveURI(URI uri)
---
public ResolvedSectionUri resolveSectionUri(String uri) {
return client.resolveURI(uri))

.map(response -> response.getEntity())

??? Try<Optional<ResolvedUri>>

}
74
Taking the happy path!
Try<RestResponse<ResolvedUri>> resolveURI(URI uri)
---
public ResolvedSectionUri resolveSectionUri(String uri) {
return client.resolveURI(uri))

.map(response -> response.getEntity().get())

??? Try<ResolvedUri>

}
75
Taking the happy path!
Try<RestResponse<ResolvedUri>> resolveURI(URI uri)
---
public ResolvedSectionUri resolveSectionUri(String uri) {
return client.resolveURI(uri))

.map(response -> (ResolvedSectionUri) response.getEntity().get())

??? Try<ResolvedSectionUri>

}
76
Taking the happy path!
Try<RestResponse<ResolvedUri>> resolveURI(URI uri)
---
public ResolvedSectionUri resolveSectionUri(String uri) {
return client.resolveURI(uri))

.map(response -> (ResolvedSectionUri) response.getEntity().get())

.orElse(null);
}
77
Taking the happy path!
Try<RestResponse<ResolvedUri>> resolveURI(URI uri)
---
public ResolvedSectionUri resolveSectionUri(String uri) {
return client.resolveURI(uri))

.map(response -> (ResolvedSectionUri) response.getEntity().get())

.orElseGet(() -> {

log.warn("Cannot resolve section from URI: {}", uri);

return null;

});
}
78
https://github.com/lambdista/try
More cool stuff in Java 8
String join
Collection removeIf (≈ filter)
Map getOrDefault, putIfAbsent, replace, forEach, etc.
java.util.Optional
java.util.stream.Collectors
count, sum, average, min, max, groupingBy, etc.
java.nio.file.Files lines
79
Functional programming
Simpler code
More robust
Better performance
Higher level
Declarative
Less verbose
Less bugs?
81
List<RoadData> filtered = new ArrayList<>();
int count = 0;
for (Iterator<RoadData> i = roadData.iterator();
i.hasNext() && count < 10; ) {
RoadData data = i.next();
if (nameQuery.matches(data.getName())) {
filtered.add(data);
count++;
}
}
roadData.stream()
.filter(data -> nameQuery.matches(data.getName()))
.limit(10)
.collect(toList());
vs.
Pure functions
82
Data In Data Out
Transformation
No external interactions
Functional core
83
————- —— —
—— —- — —- —-
—————
———
—— —- — —- —
————
—— — — — ——-
——- —- — ————
—- ——— ———
———- —— ——
—— - —-
———- — —- — -
Pure functionsI/O I/O
Building blocks
© Fredrik Vraalsen 201
What’s missing?
© Fredrik Vraalsen 2012
What’s missing?
Immutability
Value types
Data structures (lists, maps, etc.)
Concurrency
86
What’s the big deal?
Functional programming is all about values!
And transformations (functions) computing new values
Parallellism vs. Concurrency
Robustness
Testability
87
Some help to be found
Immutable collections
Google Guava, FunctionalJava, clj-ds
Concurrency mechanisms
Akka (Actors, STM)
88
github.com/krukow/clj-ds
PersistentVector<Person> people = Persistents.vector(
new Person("Fredrik", 39),
new Person("Hedda", 3));
89
github.com/krukow/clj-ds
PersistentVector<Person> people = Persistents.vector(
new Person("Fredrik", 39),
new Person("Hedda", 3));
PersistentVector<Person> morePeople =
people.plus(new Person("Johannes", 5));
90
github.com/krukow/clj-ds
PersistentVector<Person> people = Persistents.vector(
new Person("Fredrik", 39),
new Person("Hedda", 3));
PersistentVector<Person> morePeople =
people.plus(new Person("Johannes", 5));
morePeople.stream()
.forEach(p -> System.out.println(p.getName()));
91
Why use X instead?
Java 8 ready for enterprise dev?
JBoss AS, WebSphere – Nope
WildFly, GlassFish, WebLogic, Jetty, Tomcat – OK?
Important things are still missing from Java 8
Clojure and Scala available on JDK 6+!
92
Questions?
© Fredrik Vraalsen 2012
fredriv
vraalsen@iterate.no
Java 8 DOs and DON'Ts - javaBin Oslo May 2015

More Related Content

PDF
Functional programming in Java 8 - workshop at flatMap Oslo 2014
PDF
Functional programming basics
PDF
Scala - en bedre og mere effektiv Java?
PDF
Java script objects 1
 
KEY
関数潮流(Function Tendency)
PDF
Alternate JVM Languages
KEY
Commonality and Variability Analysis: Avoiding Duplicate Code
PDF
4java Basic Syntax
Functional programming in Java 8 - workshop at flatMap Oslo 2014
Functional programming basics
Scala - en bedre og mere effektiv Java?
Java script objects 1
 
関数潮流(Function Tendency)
Alternate JVM Languages
Commonality and Variability Analysis: Avoiding Duplicate Code
4java Basic Syntax

What's hot (20)

PDF
Pragmatic Real-World Scala (short version)
PDF
The Ring programming language version 1.2 book - Part 24 of 84
PDF
R Programming: Learn To Manipulate Strings In R
PPTX
Enter The Matrix
PDF
R Programming: Export/Output Data In R
PPT
PDF
PDF
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
PPTX
Collection
PDF
Scala in practice
PPTX
Giving Clarity to LINQ Queries by Extending Expressions R2
PDF
PDF
Grails: The search is over
PDF
5-minute intro to property-based testing in Python with hypothesis
PPTX
The Tools for Data Migration Between Oracle , MySQL and Flat Text File.
PDF
The Ring programming language version 1.8 book - Part 41 of 202
PDF
Meet scala
PDF
webScrapingFunctions
PDF
ORMLite Android
PDF
3 R Tutorial Data Structure
Pragmatic Real-World Scala (short version)
The Ring programming language version 1.2 book - Part 24 of 84
R Programming: Learn To Manipulate Strings In R
Enter The Matrix
R Programming: Export/Output Data In R
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
Collection
Scala in practice
Giving Clarity to LINQ Queries by Extending Expressions R2
Grails: The search is over
5-minute intro to property-based testing in Python with hypothesis
The Tools for Data Migration Between Oracle , MySQL and Flat Text File.
The Ring programming language version 1.8 book - Part 41 of 202
Meet scala
webScrapingFunctions
ORMLite Android
3 R Tutorial Data Structure
Ad

Similar to Java 8 DOs and DON'Ts - javaBin Oslo May 2015 (20)

PDF
JDK8 Functional API
PPTX
PPTX
Java 8
PDF
Java 8
PPTX
New Features in JDK 8
PDF
Java 8 - A step closer to Parallelism
PDF
Lambdas & Streams
PPTX
Java 8 - An Overview
PPTX
JDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
PPTX
New features in jdk8 iti
PPTX
Java 8 Feature Preview
PDF
PPTX
A brief tour of modern Java
PPTX
Java 8 stream and c# 3.5
PDF
Java 8 - functional features
PPTX
Java8 and Functional Programming
PDF
Master class in modern Java
PDF
Developing android apps with java 8
PPTX
FUNctional Programming in Java 8
PPTX
The Road to Lambda - Mike Duigou
JDK8 Functional API
Java 8
Java 8
New Features in JDK 8
Java 8 - A step closer to Parallelism
Lambdas & Streams
Java 8 - An Overview
JDK8 Lambdas and Streams: Changing The Way You Think When Developing Java
New features in jdk8 iti
Java 8 Feature Preview
A brief tour of modern Java
Java 8 stream and c# 3.5
Java 8 - functional features
Java8 and Functional Programming
Master class in modern Java
Developing android apps with java 8
FUNctional Programming in Java 8
The Road to Lambda - Mike Duigou
Ad

More from Fredrik Vraalsen (9)

PDF
Building applications with Serverless Framework and AWS Lambda - JavaZone 2019
PDF
Building applications with Serverless Framework and AWS Lambda
PDF
Kafka and Kafka Streams in the Global Schibsted Data Platform
PDF
Scala intro workshop
PDF
Event stream processing using Kafka streams
PDF
Hjelp, vi skal kode funksjonelt i Java!
PDF
Java 8 - Return of the Java
PDF
Java 8 to the rescue!?
ODP
Git i praksis - erfaringer med overgang fra ClearCase til Git
Building applications with Serverless Framework and AWS Lambda - JavaZone 2019
Building applications with Serverless Framework and AWS Lambda
Kafka and Kafka Streams in the Global Schibsted Data Platform
Scala intro workshop
Event stream processing using Kafka streams
Hjelp, vi skal kode funksjonelt i Java!
Java 8 - Return of the Java
Java 8 to the rescue!?
Git i praksis - erfaringer med overgang fra ClearCase til Git

Recently uploaded (20)

PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Introduction to Artificial Intelligence
PPTX
L1 - Introduction to python Backend.pptx
PDF
System and Network Administraation Chapter 3
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
System and Network Administration Chapter 2
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
AI in Product Development-omnex systems
PDF
top salesforce developer skills in 2025.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PPTX
ai tools demonstartion for schools and inter college
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Understanding Forklifts - TECH EHS Solution
Introduction to Artificial Intelligence
L1 - Introduction to python Backend.pptx
System and Network Administraation Chapter 3
VVF-Customer-Presentation2025-Ver1.9.pptx
Wondershare Filmora 15 Crack With Activation Key [2025
Navsoft: AI-Powered Business Solutions & Custom Software Development
Softaken Excel to vCard Converter Software.pdf
CHAPTER 2 - PM Management and IT Context
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Which alternative to Crystal Reports is best for small or large businesses.pdf
System and Network Administration Chapter 2
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
AI in Product Development-omnex systems
top salesforce developer skills in 2025.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
ai tools demonstartion for schools and inter college
ISO 45001 Occupational Health and Safety Management System
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...

Java 8 DOs and DON'Ts - javaBin Oslo May 2015

  • 1. Java 8 and . 1 javaBin Oslo – 12.05.2015 Fredrik Vraalsen fredriv vraalsen@iterate.no
  • 2. 2
  • 3. Java 8 – what’s new? Lambdas Method handles Extension methods Streams Optional 3
  • 4. Java 8 – what’s new? Lambdas (anonymous functions) Method handles Extension methods Streams Optional 4
  • 5. 5
  • 6. Java 7 vs 8 Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getName().compareTo(y.getName()); } }); 6
  • 7. Java 7 vs 8 Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getName().compareTo(y.getName()); } }); vs sort(people, (x, y) -> x.getName().compareTo(y.getName())); 7
  • 8. Java 7 vs 8 Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getName().compareTo(y.getName()); } }); vs sort(people, comparing(person -> person.getName())); 8
  • 9. Java 7 vs 8 Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getName().compareTo(y.getName()); } }); vs sort(people, comparing(Person::getName)); 9
  • 10. Java 7 vs 8 Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getName().compareTo(y.getName()); } }); vs people.sort(comparing(Person::getName)); 10
  • 12. Old fashioned imperative 12 List<RoadData> filtered = new ArrayList<>(); int count = 0; for (Iterator<RoadData> i = roadData.iterator(); i.hasNext() && count < 10; ) { RoadData data = i.next(); if (nameQuery.matches(data.getName())) { filtered.add(data); count++; } }
  • 14. Streams – pipelines 14 roadData.stream() .filter(data -> nameQuery.matches(data.getName())) .limit(10) .collect(toList()); cat roadData.txt | grep … | head > output.txt
  • 15. Learn you a Stream API 15
  • 16. Map<String, List<Article>> articlesByCategory = Learn you a Stream API 16
  • 17. Map<String, List<Article>> articlesByCategory = articleTransports.stream() Learn you a Stream API 17
  • 18. Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transport -> convertToArticle(transport)) Learn you a Stream API 18
  • 19. Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transport -> convertToArticle(transport)) .collect(groupingBy(article -> article.getCategory())); Learn you a Stream API 19
  • 20. Method handles 20 Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transport -> convertToArticle(transport)) .collect(groupingBy(article -> article.getCategory()));
  • 21. Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::convertToArticle) .collect(groupingBy(article -> article.getCategory())); Method handles 21
  • 22. Method handles 22 Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::convertToArticle) .collect(groupingBy(Article::getCategory));
  • 23. Naming, caching, counting 23 Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::convertToArticle) .collect(groupingBy(Article::getCategory));
  • 24. Naming, caching, counting 24 Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::transportToArticle) .collect(groupingBy(Article::category));
  • 25. Extract functions 25 Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transportToArticle) .collect(groupingBy(Article::category)); Function<ArticleTransport, Article> transportToArticle = transport -> convertToArticle(transport);
  • 26. Lambdas everywhere!!!1! links.stream() .map(link -> link.build()) .forEach(abderaElement::addLink); 26
  • 27. Old school ifs and fors links.stream() .map(link -> link.build()) .forEach(abderaElement::addLink); for (LinkBuilder lb : links) {
 abderaElement.addLink(lb.build());
 } 27
  • 28. Parsing nested JSON "suggest": { "tag_suggest": [ { "length": 5, "offset": 0, "options": [ { "freq": 25, "score": 0.8, "text": "fakta" } ], "text": "fanta" } ] } 28
  • 29. Lambdas everywhere!!!1! List<String> terms = new ArrayList<>();
 suggestions.getAsJsonObject().getAsJsonArray(“tag_suggest”)
 .forEach(tag -> tag.getAsJsonObject().getAsJsonArray("options")
 .forEach(option -> terms
 .add(option.getAsJsonObject().getAsJsonPrimitive("text")
 .getAsString())));
 29
  • 30. Old school ifs and fors List<String> terms = new ArrayList<>();
 for (JsonElement tag : suggestions.getAsJsonObject().getAsJsonArray("tag_suggest")) {
 for (JsonElement option : tag.getAsJsonObject().getAsJsonArray("options")) {
 terms.add(option.getAsJsonObject().getAsJsonPrimitive("text").getAsString());
 }
 }
 30
  • 31. Old school ifs and fors List<String> terms = new ArrayList<>();
 for (JsonElement tag : getAll("tag_suggest", suggestions)) {
 for (JsonElement option : getAll("options", tag)) {
 terms.add(getString("text", option));
 }
 }
 31
  • 32. List<String> terms = getAll("tag_suggest", suggestions).stream()
 .flatMap(tag -> getAll("options", tag).stream())
 .map(option -> getString("text", option))
 .collect(Collectors.toList()); 32 Lambdas everywhere!!!1!
  • 33. Readability ≫ Style / LOC Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live. http://c2.com/cgi/wiki?CodeForTheMaintainer
  • 35. Optional<T> Wrapper object Make explicit if a value is present or absent (empty) 35
  • 36. Optional example public Optional<Image> getImage(Article article) --- 36
  • 37. Optional example public Optional<Image> getImage(Article article) --- Optional<Image> image = getImage(article); 37
  • 38. Check presence public Optional<Image> getImage(Article article) --- Optional<Image> image = getImage(article); if (image.isPresent()) { doSomething(image.get()); } 38
  • 39. Check presence public Optional<Image> getImage(Article article) --- Optional<Image> image = getImage(article); image.ifPresent(img -> doSomething(img)); 39
  • 40. Check presence public Optional<Image> getImage(Article article) --- getImage(article).ifPresent(image -> doSomething(image)); 40
  • 41. Default / fallback value public Optional<Image> getImage(Article article) --- Image image = getImage(article).orElse(defaultImage); 41
  • 42. Optional in / Optional out public Optional<String> getCaption(Optional<Image> image) --- Optional<Image> image = getImage(article); Optional<String> caption = getCaption(image); 42
  • 43. Optional in / Optional out public String getCaption(Image image) --- Optional<Image> image = getImage(article); Optional<String> caption = ??? 43
  • 44. Reaching into the void … public String getCaption(Image image) --- Optional<Image> image = getImage(article); Optional<String> caption = image.map(img -> getCaption(img)); 44
  • 45. Reaching into the void … public String getCaption(Image image) --- Optional<String> caption = getImage(article) .map(img -> getCaption(image)); 45
  • 46. Bye bye NullPointerException? Marker – this may not return/contain value Public APIs Not a general solution to NPEs 46
  • 47. Optional + Streams = true? 47
  • 48. Optional + Streams = true? 48 myStream.map(v -> functionReturningOptional(v))
  • 49. Optional + Streams = true? 49 myStream.map(v -> functionReturningOptional(v)) Stream<Optional<T>>
  • 50. Optional + Streams = true? 50 myStream.map(v -> functionReturningOptional(v)) Stream<Optional<T>> Stream<T> ???
  • 52. Optional + Streams = true? 52 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
  • 53. Optional + Streams = true? 53 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .map(article -> getImage(article)) // Stream<Optional<Image>>
  • 54. Optional + Streams = true? 54 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .map(article -> getImage(article)) // Stream<Optional<Image>> .filter(Optional::ifPresent) .map(Optional::get) // Stream<Image>

  • 55. Optional + Streams = true? 55 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .map(article -> getImage(article)) // Stream<Optional<Image>> .filter(Optional::ifPresent) .map(Optional::get) // Stream<Image>
 .collect(toList());
  • 56. flatMap to the rescue! flatMap = map + flatten Stream<Stream<T>> Stream<T> 56
  • 57. flatMap to the rescue! flatMap = map + flatten Stream<Optional<T>> Stream<T> ??? 57
  • 58. flatMap to the rescue! Easy to create helper functions Stream<T> toStream(Optional<T> optValue) 58 http://stackoverflow.com/questions/22725537/using-java-8s-optional-with-streamflatmap
  • 59. Optional + Streams = true? 59 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .map(article -> getImage(article)) // Stream<Optional<Image>> .filter(Optional::ifPresent) .map(Optional::get) // Stream<Image>
 .collect(toList());
  • 60. Optional + Streams = true 60 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .flatMap(article -> toStream(getImage(article))) // Stream<Image>
 .collect(toList());
  • 61. Optional + Streams = true 61 public Optional<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .flatMap(article -> getImage(article).stream()) // Stream<Image>
 .collect(toList()); Java 9 https://bugs.openjdk.java.net/browse/JDK-8050820
  • 62. Take one stream and pass it around… 62 public Stream<Image> getImage(Article article) --- List<Image> images = articles.stream() // Stream<Article>
 .flatMap(article -> getImage(article)) // Stream<Image>
 .collect(toList());
  • 63. No method handle for you! 63 private Article elementToArticle(Map contentById, Element el) --- List<Article> articles = elements.stream()
 .map(el -> elementToArticle(contentById, el))
 .collect(toList())
  • 65. Yummy currying!! 65 Mapper mapper = new Mapper(contentById); --- List<Article> articles = elements.stream()
 .map(el -> mapper.elementToArticle(el))
 .collect(toList())
  • 66. Yummy currying!! 66 Mapper mapper = new Mapper(contentById); --- List<Article> articles = elements.stream()
 .map(mapper::elementToArticle)
 .collect(toList())
  • 68. Streams – performance List<Article> frontpageArticles = frontpage.getArticleIds().stream() .map(id -> fetchArticle(id)) .collect(toList()); 68
  • 69. This one goes to 11! List<Article> frontpageArticles = frontpage.getArticleIds().parallelStream() .map(id -> fetchArticle(id)) .collect(toList()); 69
  • 70. Starvation Common F/J thread pool Workarounds? Execute within explicit F/J pool Use CompletableFuture 70
  • 71. CompletableFuture Chaining of async futures and actions Waiting for all or any future(s) Explicitly complete (like Promise) Control of executor service 71 http://blog.krecan.net/2014/03/18/how-to-specify-thread-pool-for-java-8-parallel-streams/ http://www.nurkiewicz.com/2013/05/java-8-completablefuture-in-action.html
  • 72. To parallelStream or not to … Batch? parallelStream FTW! Interactive? Concurrency? CompletableFuture FTW! 72
  • 73. Taking the happy path! Try<RestResponse<ResolvedUri>> resolveURI(URI uri) --- public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri)) ??? Try<RestResponse<ResolvedUri>>
 } 73
  • 74. Taking the happy path! Try<RestResponse<ResolvedUri>> resolveURI(URI uri) --- public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri))
 .map(response -> response.getEntity())
 ??? Try<Optional<ResolvedUri>>
 } 74
  • 75. Taking the happy path! Try<RestResponse<ResolvedUri>> resolveURI(URI uri) --- public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri))
 .map(response -> response.getEntity().get())
 ??? Try<ResolvedUri>
 } 75
  • 76. Taking the happy path! Try<RestResponse<ResolvedUri>> resolveURI(URI uri) --- public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri))
 .map(response -> (ResolvedSectionUri) response.getEntity().get())
 ??? Try<ResolvedSectionUri>
 } 76
  • 77. Taking the happy path! Try<RestResponse<ResolvedUri>> resolveURI(URI uri) --- public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri))
 .map(response -> (ResolvedSectionUri) response.getEntity().get())
 .orElse(null); } 77
  • 78. Taking the happy path! Try<RestResponse<ResolvedUri>> resolveURI(URI uri) --- public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri))
 .map(response -> (ResolvedSectionUri) response.getEntity().get())
 .orElseGet(() -> {
 log.warn("Cannot resolve section from URI: {}", uri);
 return null;
 }); } 78 https://github.com/lambdista/try
  • 79. More cool stuff in Java 8 String join Collection removeIf (≈ filter) Map getOrDefault, putIfAbsent, replace, forEach, etc. java.util.Optional java.util.stream.Collectors count, sum, average, min, max, groupingBy, etc. java.nio.file.Files lines 79
  • 80. Functional programming Simpler code More robust Better performance
  • 81. Higher level Declarative Less verbose Less bugs? 81 List<RoadData> filtered = new ArrayList<>(); int count = 0; for (Iterator<RoadData> i = roadData.iterator(); i.hasNext() && count < 10; ) { RoadData data = i.next(); if (nameQuery.matches(data.getName())) { filtered.add(data); count++; } } roadData.stream() .filter(data -> nameQuery.matches(data.getName())) .limit(10) .collect(toList()); vs.
  • 82. Pure functions 82 Data In Data Out Transformation No external interactions
  • 83. Functional core 83 ————- —— — —— —- — —- —- ————— ——— —— —- — —- — ———— —— — — — ——- ——- —- — ———— —- ——— ——— ———- —— —— —— - —- ———- — —- — - Pure functionsI/O I/O
  • 86. What’s missing? Immutability Value types Data structures (lists, maps, etc.) Concurrency 86
  • 87. What’s the big deal? Functional programming is all about values! And transformations (functions) computing new values Parallellism vs. Concurrency Robustness Testability 87
  • 88. Some help to be found Immutable collections Google Guava, FunctionalJava, clj-ds Concurrency mechanisms Akka (Actors, STM) 88
  • 89. github.com/krukow/clj-ds PersistentVector<Person> people = Persistents.vector( new Person("Fredrik", 39), new Person("Hedda", 3)); 89
  • 90. github.com/krukow/clj-ds PersistentVector<Person> people = Persistents.vector( new Person("Fredrik", 39), new Person("Hedda", 3)); PersistentVector<Person> morePeople = people.plus(new Person("Johannes", 5)); 90
  • 91. github.com/krukow/clj-ds PersistentVector<Person> people = Persistents.vector( new Person("Fredrik", 39), new Person("Hedda", 3)); PersistentVector<Person> morePeople = people.plus(new Person("Johannes", 5)); morePeople.stream() .forEach(p -> System.out.println(p.getName())); 91
  • 92. Why use X instead? Java 8 ready for enterprise dev? JBoss AS, WebSphere – Nope WildFly, GlassFish, WebLogic, Jetty, Tomcat – OK? Important things are still missing from Java 8 Clojure and Scala available on JDK 6+! 92
  • 93. Questions? © Fredrik Vraalsen 2012 fredriv vraalsen@iterate.no