Page 1
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
[email protected]
@victorrentea
© Copyright Victor Rentea 2017
Page 2
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
[email protected] www.victorrentea.ro@victorrentea2
Page 3
VictorRentea.ro
They are cool
Expressive code- .filter(Order::isActive)
Concise code (½ lines?)
Cryptic? Hard to read?- What guidelines to follow ?
Why Lambdas ?
3
Page 4
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
Page 5
VictorRentea.ro
Workshop: Searching Streams (30 min)
Workshop: Transforming Streams (40 min)
Workshop: Cleaning Lambdas (20 min)
Conclusions: Best Practices (20 min)
Agenda
5
Page 6
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
Page 10
VictorRentea.ro10
Page 11
VictorRentea.ro11
Page 12
VictorRentea.ro12< 6 mo
> 6 mo
Page 13
VictorRentea.ro13
Page 14
VictorRentea.ro14
Page 15
VictorRentea.ro15
< 6 mo
> 6 mo
Page 16
VictorRentea.ro16
Page 17
VictorRentea.ro17
Page 18
VictorRentea.ro18
< 6 mo
> 6 mo
Page 19
VictorRentea.ro19< 6 mo
> 6 mo
Page 20
VictorRentea.ro20
Page 21
VictorRentea.ro21
Page 23
VictorRentea.ro23
Page 24
VictorRentea.ro24
Page 25
VictorRentea.ro25
Page 26
VictorRentea.ro26
Page 27
VictorRentea.ro27
< 6 mo
> 6 mo
Page 28
VictorRentea.ro28
< 6 mo
> 6 mo
Page 29
VictorRentea.ro29
Page 30
VictorRentea.ro30
Page 31
VictorRentea.ro31
Page 32
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
𝒇(𝑶𝒓𝒅𝒆𝒓):𝑫𝒂𝒕𝒆
𝒇(𝑺𝒕𝒓𝒊𝒏𝒈): 𝒊𝒏𝒕
𝒇(𝑶𝒓𝒅𝒆𝒓𝑴𝒂𝒑𝒑𝒆𝒓,𝑶𝒓𝒅𝒆𝒓):𝑶𝒓𝒅𝒆𝒓𝑫𝒕𝒐
𝒇(): 𝑫𝒂𝒕𝒆
𝒇(): 𝒊𝒏𝒕
𝒇 𝑶𝒓𝒅𝒆𝒓 :𝑶𝒓𝒅𝒆𝒓𝑫𝒕𝒐
𝒇(𝑺𝒕𝒓𝒊𝒏𝒈): 𝒊𝒏𝒕𝒇(): 𝑫𝒂𝒕𝒆
𝒇(𝑳𝒐𝒏𝒈):𝑫𝒂𝒕𝒆
Page 33
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
Page 34
VictorRentea.ro34
Page 35
VictorRentea.ro
flatMap(i -> i.getChildren().stream())
35
Page 36
VictorRentea.ro
2 4 1 3
0 2+
.reduce(0, +)
6+ 7+ 10+
36
Page 37
VictorRentea.ro37
Page 38
VictorRentea.ro38
< 6 mo
> 6 mo
Page 39
VictorRentea.ro39
< 6 mo
> 6 mo
Page 40
VictorRentea.ro40
Page 41
VictorRentea.ro41
Page 42
VictorRentea.ro42
Page 43
VictorRentea.ro43
Page 44
VictorRentea.ro44
Page 45
VictorRentea.ro45
Page 46
VictorRentea.ro46
Page 47
VictorRentea.ro47
Page 48
VictorRentea.ro48
Page 49
VictorRentea.ro49
Page 50
VictorRentea.ro50
orders.stream()
.filter(Order::isActive)
.map(Order::getCreationDate)
.collect(toList())
Page 51
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!
Page 52
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
Page 53
VictorRentea.ro53
.filter(Order::isActive)
.map(Order::getCreationDate)
.findFirst()
orders.stream() AR
E NEV
ER SEEN
I’m done.
Page 54
VictorRentea.ro54
Short Circuiting
Page 55
VictorRentea.ro55
Page 56
VictorRentea.ro56
The most important principle in Programming?
Page 57
VictorRentea.ro57
ingle esponsibility rincipleS R P
Page 58
VictorRentea.ro58
Keep It Short & SimpleK I S S
Page 59
VictorRentea.ro59
KISS
(or nullable): SRP
Work with predicates(coming up next)
Simple code
Look for the simplest
form
Page 60
VictorRentea.ro60
Pair Programming
Page 61
VictorRentea.ro61
Page 62
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
Page 63
VictorRentea.ro63
Page 64
VictorRentea.ro64
Find the shortest form(peer review)
Don’t abuse them
Clean Code Using Java8 New Features(lambdas, Stream, Optional)
Page 65
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
Page 66
Enterprise Java Training
www.victorrentea.ro
[email protected]
@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