Clean Lambdas & Streams in Java8

Preview:

Citation preview

Enterprise Java Training

Victor Rentea

10 March 2017

Clean Lambdas & Streams in Java 8A Hands-on Experience

Workshop: Searching Streams (30 min)

Workshop: Transforming Streams (40 min)

Workshop: Cleaning Lambdas (20 min)

Conclusions: Best Practices (20 min)

Ag

en

da www.victorrentea.ro

victor.rentea@gmail.com

@victorrentea

© Copyright Victor Rentea 2017

VictorRentea.ro

Clean Code Evangelist

International Speaker Spring and

Clean Code, Design Patterns ( )

TDD, Coding Dojos

Java Performance

many more:

Victor Rentea, PhD(CS)Consultant, Technical Lead

Lead Architect for major client at IBM Romania

Night Job :

Freelance Trainer & Coach

victorrentea@gmail.com www.victorrentea.ro@victorrentea2

VictorRentea.ro

They are cool

Expressive code- .filter(Order::isActive)

Concise code (½ lines?)

Cryptic? Hard to read?- What guidelines to follow ?

Why Lambdas ?

3

VictorRentea.ro

Which λ to use in enterprise Java apps ?- Readable, maintainable

- vs Java7

-

Questionnaire-based- Java8 features in examples from production

- For Java developers of any exp level (min 3 months of Java8 hands-on)

- Wanna submit you answer? Thank you !! : http://bit.ly/2dFf2fi

My own little

Clean Lambdas Study

4

VictorRentea.ro

Workshop: Searching Streams (30 min)

Workshop: Transforming Streams (40 min)

Workshop: Cleaning Lambdas (20 min)

Conclusions: Best Practices (20 min)

Agenda

5

VictorRentea.ro

// Cool Class Diagram[Order|id:Long;creationDate;paymentMethod;status:Status;totalPrice:BigDecimal]-orderLines*>[OrderLine|count:int;isSpecialOffer][OrderLine]-product>[Product|name]

[Audit|action;date;user;modifiedField]

Before we start: configure your IDE to suggest static imports of:java.util.stream.Collectors.* and java.util.Comparator.comparing

In Eclipse: Preferences > type “favo” > Favorites > New Type & New Member

Our Domain Model

6

VictorRentea.ro7

VictorRentea.ro8

VictorRentea.ro9

VictorRentea.ro10

VictorRentea.ro11

VictorRentea.ro12< 6 mo

> 6 mo

VictorRentea.ro13

VictorRentea.ro14

VictorRentea.ro15

< 6 mo

> 6 mo

VictorRentea.ro16

VictorRentea.ro17

VictorRentea.ro18

< 6 mo

> 6 mo

VictorRentea.ro19< 6 mo

> 6 mo

VictorRentea.ro20

VictorRentea.ro21

22

VictorRentea.ro23

VictorRentea.ro24

VictorRentea.ro25

VictorRentea.ro26

VictorRentea.ro27

< 6 mo

> 6 mo

VictorRentea.ro28

< 6 mo

> 6 mo

VictorRentea.ro29

VictorRentea.ro30

VictorRentea.ro31

VictorRentea.ro

static method constructor

Method References

32

Integer::parseInt

Order::getCreationDate

OrderMapper::toDto

String::length

myOrder::getCreationDate

orderMapper::toDto

firstName::length

Date::new

... of a class … of an instanceinstance method

instanceis known

𝒇(𝑶𝒓𝒅𝒆𝒓):𝑫𝒂𝒕𝒆

𝒇(𝑺𝒕𝒓𝒊𝒏𝒈): 𝒊𝒏𝒕

𝒇(𝑶𝒓𝒅𝒆𝒓𝑴𝒂𝒑𝒑𝒆𝒓,𝑶𝒓𝒅𝒆𝒓):𝑶𝒓𝒅𝒆𝒓𝑫𝒕𝒐

𝒇(): 𝑫𝒂𝒕𝒆

𝒇(): 𝒊𝒏𝒕

𝒇 𝑶𝒓𝒅𝒆𝒓 :𝑶𝒓𝒅𝒆𝒓𝑫𝒕𝒐

𝒇(𝑺𝒕𝒓𝒊𝒏𝒈): 𝒊𝒏𝒕𝒇(): 𝑫𝒂𝒕𝒆

𝒇(𝑳𝒐𝒏𝒈):𝑫𝒂𝒕𝒆

VictorRentea.ro

= (String s) -> {return s.length();};

Function<String, Integer> stringLen = (String s) -> s.length(); // implicit return

= s -> s.length();

= String :: length;

Comparator<User> fNameComparator = (u1,u2)-> u1.getFName().compareTo(u2.getFName());

= Comparator.comparing(User :: getFName);

Predicate<Apple> appleIsHeavy = a -> a.getWeight() > 150;

= Apple :: isHeavy;

Consumer<String> stringPrinter = s -> System.out.println(s); // returns void

= System.out::println;

Supplier<Wine> firstMiracle = () -> new Wine();

= Wine :: new;

𝒇 𝑺𝒕𝒓𝒊𝒏𝒈 : 𝑰𝒏𝒕𝒆𝒈𝒆𝒓

𝒇 𝑼𝒔𝒆𝒓,𝑼𝒔𝒆𝒓 : 𝒊𝒏𝒕

𝒇 𝑨𝒑𝒑𝒍𝒆 : 𝒃𝒐𝒐𝒍𝒆𝒂𝒏

𝒇 𝑺𝒕𝒓𝒊𝒏𝒈

𝒇():𝑾𝒊𝒏𝒆 ʎ syntax33

VictorRentea.ro34

VictorRentea.ro

flatMap(i -> i.getChildren().stream())

35

VictorRentea.ro

2 4 1 3

0 2+

.reduce(0, +)

6+ 7+ 10+

36

VictorRentea.ro37

VictorRentea.ro38

< 6 mo

> 6 mo

VictorRentea.ro39

< 6 mo

> 6 mo

VictorRentea.ro40

VictorRentea.ro41

VictorRentea.ro42

VictorRentea.ro43

VictorRentea.ro44

VictorRentea.ro45

VictorRentea.ro46

VictorRentea.ro47

VictorRentea.ro48

VictorRentea.ro49

VictorRentea.ro50

orders.stream()

.filter(Order::isActive)

.map(Order::getCreationDate)

.collect(toList())

VictorRentea.ro51

orders.stream()

.filter(Order::isActive)

.map(Order::getCreationDate)

.collect(toList())

Give me!Here you go!

Give me!

Give me!

Argh!Another one!

Here you go!

VictorRentea.ro52

.filter(Order::isActive)

orders.stream()

.map(Order::getCreationDate)

Give me! Nope! I’m done.

.collect(toList())

.limit(3)

AR

E NEV

ER SEEN

VictorRentea.ro53

.filter(Order::isActive)

.map(Order::getCreationDate)

.findFirst()

orders.stream() AR

E NEV

ER SEEN

I’m done.

VictorRentea.ro54

Short Circuiting

VictorRentea.ro55

VictorRentea.ro56

The most important principle in Programming?

VictorRentea.ro57

ingle esponsibility rincipleS R P

VictorRentea.ro58

Keep It Short & SimpleK I S S

VictorRentea.ro59

KISS

(or nullable): SRP

Work with predicates(coming up next)

Simple code

Look for the simplest

form

VictorRentea.ro60

Pair Programming

VictorRentea.ro61

VictorRentea.ro

public static Predicate<Order> deliveryDueBefore(Date date) {

return order -> order.getDeliveryDueDate().before(date);

}

Clean Lambdas

Encapsulate Predicates

Predicate<Order> needsTracking = order -> order.hasPoliticalCustomer();

Set<Customer> customersToNotify = orders.stream()

.filter(order -> order.getDeliveryDueDate().before(warningDate) &&

order.getOrderLines().stream()

.anyMatch(line -> line.getStatus() != Status.IN_STOCK))

.map(Order::getCustomer)

.collect(toSet());

.filter(order -> order.getDeliveryDueDate().before(warningDate))

.filter(order -> order.getOrderLines().stream()

.anyMatch(line -> line.getStatus() != Status.IN_STOCK))(OrderLine::isNotInStock))

.filter(this::hasOrdersNotInStock)

<entity>

OrderLine

<service>

NotificationService(this)

OrderPredicates.deliveryDueBefore(warningDate))deliveryDueBefore(warningDate)).or(this::needsTracking))

<utility>

OrderPredicates

In entities

In the class needing it

As functions returning Predicates

Auxiliary Predicate variables

62

VictorRentea.ro63

VictorRentea.ro64

Find the shortest form(peer review)

Don’t abuse them

Clean Code Using Java8 New Features(lambdas, Stream, Optional)

VictorRentea.ro

Resources

Java 8 in Action by Raoul-Gabriel Urma, Mario Fusco, Alan Mycroft, 2015

https://blog.jetbrains.com/idea/2016/07/java-8-top-tips/

https://github.com/jOOQ/jOOL

Clean Code by Robert C. Martin

https://zeroturnaround.com/rebellabs/java-8-best-practices-cheat-sheet/

https://www.journeytomastery.net/2015/03/22/clean-code-and-java-8/

Curious about Java9: https://bentolor.github.io/java9-in-action/

65

Enterprise Java Training

www.victorrentea.ro

victor.rentea@gmail.com

@victorrentea

Workshop: Searching Streams (30 min)

Workshop: Transforming Streams (40 min)

Workshop: Cleaning Lambdas (20 min)

Conclusions: Best Practices (20 min)

© Copyright Victor Rentea 2017

Victor Rentea

10 March 2017

Clean Lambdas & Streams in Java 8A Hands-on Experience