Post on 11-Apr-2017
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