java 8 dos and don'ts - javabin oslo may 2015

94
Java 8 and . 1 javaBin Oslo 12.05.2015 Fredrik Vraalsen fredriv [email protected]

Upload: fredrik-vraalsen

Post on 08-Aug-2015

338 views

Category:

Software


0 download

TRANSCRIPT

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

Java 8 and .

1

javaBin Oslo – 12.05.2015

Fredrik Vraalsen

fredriv [email protected]

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

2

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

Java 8 – what’s new?Lambdas

Method handles

Extension methods

Streams

Optional3

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

Java 8 – what’s new?Lambdas (anonymous functions)

Method handles

Extension methods

Streams

Optional4

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

5

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

Java 7 vs 8Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getName().compareTo(y.getName()); } });

6

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

Java 7 vs 8Collections.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

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

Java 7 vs 8Collections.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

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

Java 7 vs 8Collections.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

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

Java 7 vs 8Collections.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

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

Streams

© Fredrik Vraalsen 2008

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

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++; }}

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

Streams

13

roadData.stream() .filter(data -> nameQuery.matches(data.getName())) .limit(10) .collect(toList());

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

Streams – pipelines

14

roadData.stream() .filter(data -> nameQuery.matches(data.getName())) .limit(10) .collect(toList());

cat roadData.txt | grep … | head > output.txt

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

Learn you a Stream API

15

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

Map<String, List<Article>> articlesByCategory =

Learn you a Stream API

16

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

Map<String, List<Article>> articlesByCategory = articleTransports.stream()

Learn you a Stream API

17

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

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transport -> convertToArticle(transport))

Learn you a Stream API

18

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

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transport -> convertToArticle(transport)) .collect(groupingBy(article -> article.getCategory()));

Learn you a Stream API

19

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

Method handles

20

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transport -> convertToArticle(transport)) .collect(groupingBy(article -> article.getCategory()));

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

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::convertToArticle) .collect(groupingBy(article -> article.getCategory()));

Method handles

21

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

Method handles

22

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::convertToArticle) .collect(groupingBy(Article::getCategory));

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

Naming, caching, counting

23

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::convertToArticle) .collect(groupingBy(Article::getCategory));

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

Naming, caching, counting

24

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(this::transportToArticle) .collect(groupingBy(Article::category));

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

Extract functions

25

Map<String, List<Article>> articlesByCategory = articleTransports.stream() .map(transportToArticle) .collect(groupingBy(Article::category));

Function<ArticleTransport, Article> transportToArticle = transport -> convertToArticle(transport);

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

Lambdas everywhere!!!1!links.stream() .map(link -> link.build()) .forEach(abderaElement::addLink);

26

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

Old school ifs and forslinks.stream() .map(link -> link.build()) .forEach(abderaElement::addLink);

for (LinkBuilder lb : links) { abderaElement.addLink(lb.build()); }

27

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

Parsing nested JSON "suggest": { "tag_suggest": [ { "length": 5, "offset": 0, "options": [ { "freq": 25, "score": 0.8, "text": "fakta" } ], "text": "fanta" } ] } 28

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

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

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

Old school ifs and forsList<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

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

Old school ifs and forsList<String> terms = new ArrayList<>();

for (JsonElement tag : getAll("tag_suggest", suggestions)) { for (JsonElement option : getAll("options", tag)) { terms.add(getString("text", option)); } }

31

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

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!

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

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

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

OH NOES

NullPointerException!!?!© Fredrik Vraalsen 201

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

Optional<T>Wrapper object

Make explicit if a value is present or absent (empty)

35

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

Optional examplepublic Optional<Image> getImage(Article article)

---

36

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

Optional examplepublic Optional<Image> getImage(Article article)

---

Optional<Image> image = getImage(article);

37

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

Check presencepublic Optional<Image> getImage(Article article)

---

Optional<Image> image = getImage(article);if (image.isPresent()) { doSomething(image.get());}

38

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

Check presencepublic Optional<Image> getImage(Article article)

---

Optional<Image> image = getImage(article);image.ifPresent(img -> doSomething(img));

39

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

Check presencepublic Optional<Image> getImage(Article article)

---

getImage(article).ifPresent(image -> doSomething(image));

40

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

Default / fallback valuepublic Optional<Image> getImage(Article article)

---

Image image = getImage(article).orElse(defaultImage);

41

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

Optional in / Optional outpublic Optional<String> getCaption(Optional<Image> image)

---

Optional<Image> image = getImage(article);Optional<String> caption = getCaption(image);

42

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

Optional in / Optional outpublic String getCaption(Image image)

---

Optional<Image> image = getImage(article);Optional<String> caption = ???

43

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

Reaching into the void …public String getCaption(Image image)

---

Optional<Image> image = getImage(article);Optional<String> caption = image.map(img -> getCaption(img));

44

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

Reaching into the void …public String getCaption(Image image)

---

Optional<String> caption = getImage(article) .map(img -> getCaption(image));

45

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

Bye bye NullPointerException?Marker – this may not return/contain value

Public APIs

Not a general solution to NPEs

46

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

Optional + Streams = true?

47

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

Optional + Streams = true?

48

myStream.map(v -> functionReturningOptional(v))

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

Optional + Streams = true?

49

myStream.map(v -> functionReturningOptional(v))

Stream<Optional<T>>

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

Optional + Streams = true?

50

myStream.map(v -> functionReturningOptional(v))

Stream<Optional<T>> ⇒ Stream<T> ???

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

Guava Optional

51

Iterable<T> presentInstances(Iterable<Optional<T>> optionals)

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

Optional + Streams = true?

52

public Optional<Image> getImage(Article article)

---

List<Image> images = articles.stream() // Stream<Article>

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

Optional + Streams = true?

53

public Optional<Image> getImage(Article article)

---

List<Image> images = articles.stream() // Stream<Article> .map(article -> getImage(article)) // Stream<Optional<Image>>

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

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>

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

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());

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

flatMap to the rescue!flatMap = map + flatten

Stream<Stream<T>> ⇒ Stream<T>

56

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

flatMap to the rescue!flatMap = map + flatten

Stream<Optional<T>> ⇒ Stream<T> ???

57

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

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

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

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());

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

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());

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

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

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

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());

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

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

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

64

http://en.wikipedia.org/wiki/Malabar_matthi_curry#/media/File:Meen_curry_2_(cropped).JPG

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

Yummy currying!!

65

Mapper mapper = new Mapper(contentById);

---

List<Article> articles = elements.stream() .map(el -> mapper.elementToArticle(el)) .collect(toList())

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

Yummy currying!!

66

Mapper mapper = new Mapper(contentById);

---

List<Article> articles = elements.stream() .map(mapper::elementToArticle) .collect(toList())

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

Performance

© Fredrik Vraalsen 2012

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

Streams – performanceList<Article> frontpageArticles = frontpage.getArticleIds().stream() .map(id -> fetchArticle(id)) .collect(toList());

68

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

This one goes to 11!List<Article> frontpageArticles = frontpage.getArticleIds().parallelStream() .map(id -> fetchArticle(id)) .collect(toList());

69

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

StarvationCommon F/J thread pool

Workarounds?

Execute within explicit F/J pool

Use CompletableFuture

70

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

CompletableFutureChaining 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

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

To parallelStream or not to …Batch?

parallelStream FTW!

Interactive? Concurrency?

CompletableFuture FTW!72

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

Taking the happy path!Try<RestResponse<ResolvedUri>> resolveURI(URI uri)

---

public ResolvedSectionUri resolveSectionUri(String uri) { return client.resolveURI(uri))

??? Try<RestResponse<ResolvedUri>>

}

73

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

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

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

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

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

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

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

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

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

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

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

More cool stuff in Java 8String 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 lines79

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

Functional programmingSimpler code

More robust

Better performance

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

Higher levelDeclarative

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.

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

Pure functions

82

Data In Data Out

Transformation

No external interactions

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

Functional core

83

————- —— ——— —- — —- —-—————————— —- — —- ——————— — — — ——-——- —- — —————- ——— ——————- —— ———— - —-———- — —- — -

Pure functionsI/O I/O

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

Building blocks

© Fredrik Vraalsen 201

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

What’s missing?© Fredrik Vraalsen 2012

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

What’s missing?Immutability

Value types

Data structures (lists, maps, etc.)

Concurrency

86

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

What’s the big deal?Functional programming is all about values!

And transformations (functions) computing new values

Parallellism vs. Concurrency

Robustness

Testability

87

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

Some help to be foundImmutable collections

Google Guava, FunctionalJava, clj-ds

Concurrency mechanisms

Akka (Actors, STM)

88

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

github.com/krukow/clj-dsPersistentVector<Person> people = Persistents.vector( new Person("Fredrik", 39), new Person("Hedda", 3));

89

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

github.com/krukow/clj-dsPersistentVector<Person> people = Persistents.vector( new Person("Fredrik", 39), new Person("Hedda", 3));

PersistentVector<Person> morePeople = people.plus(new Person("Johannes", 5));

90

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

github.com/krukow/clj-dsPersistentVector<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

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

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

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

Questions?

© Fredrik Vraalsen 2012

fredriv

[email protected]

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