SlideShare a Scribd company logo
Pragmatic Functional 
Refactoring with Java 8 
Raoul-Gabriel Urma (@raoulUK) 
Richard Warburton (@RichardWarburto)
Pragmatic Functional Refactoring with Java 8
Pragmatic Functional Refactoring with Java 8
First-class Functions 
Currying 
Immutability 
Optional Data Types 
Conclusions
Step 1: filtering invoices from Oracle 
public List<Invoice> findInvoicesFromOracle(List<Invoice> invoices) { 
List<Invoice> result = new ArrayList<>(); 
for(Invoice invoice: invoices) { 
if( invoice.getCustomer() == Customer.ORACLE) { 
result.add(invoice); 
} 
} 
return result; 
}
Step 2a: abstracting the customer 
public List<Invoice> findInvoicesFromCustomer(List<Invoice> invoices, 
Customer customer) { 
List<Invoice> result = new ArrayList<>(); 
for(Invoice invoice: invoices) { 
if( invoice.getCustomer() == customer) { 
result.add(invoice); 
} 
} 
return result; 
}
Step 2b: abstracting the name 
public List<Invoice> findInvoicesEndingWith(List<Invoice> invoices, 
String suffix) { 
List<Invoice> result = new ArrayList<>(); 
for(Invoice invoice: invoices) { 
if( invoice.getName().endsWith(suffix)) { 
result.add(invoice); 
} 
} 
return result; 
}
Step 3: messy code-reuse! 
private List<Invoice> findInvoices(List<Invoice> invoices, 
Customer customer, 
String suffix, 
boolean flag) { 
List<Invoice> result = new ArrayList<>(); 
for(Invoice invoice: invoices) { 
if(( flag && invoice.getCustomer() == customer) 
|| (!flag && invoice.getName().endsWith(suffix))) { 
result.add(invoice); 
} 
} 
return result; 
}
Step 4a: modeling the filtering criterion 
public interface Predicate<T> { 
boolean test(T t); 
} 
Invoice boolean 
Predicate<Invoice>
Step 4b: using different criterion with objects 
private List<Invoice> findInvoices(List<Invoice> invoices, 
Predicate<Invoice> p) { 
List<Invoice> result = new ArrayList<>(); 
for(Invoice invoice: invoices) { 
if( p.test(invoice)) { 
result.add(invoice); 
} 
} 
return result; 
}
Step 4b: using different criterion with objects 
List<Invoice> specificInvoices = 
findInvoices(invoices, new FacebookTraining()); 
class FacebookTraining implements Predicate<Invoice> { 
@Override 
public boolean test(Invoice invoice) { 
return invoice.getCustomer() == Customer.FACEBOOK 
&& invoice.getName().endsWith("Training"); 
} 
}
Step 5: method references 
public boolean isOracleInvoice(Invoice invoice) { 
return invoice.getCustomer() == Customer.ORACLE; 
} 
public boolean isTrainingInvoice(Invoice invoice) { 
return invoice.getName().endsWith("Training"); 
} 
List<Invoice> oracleInvoices = 
findInvoices(invoices, this::isOracleInvoice); 
List<Invoice> trainingInvoices = 
findInvoices(invoices, this::isTrainingInvoice); 
method references
Step 6: lambdas 
List<Invoice> oracleInvoices = 
findInvoices(invoices, 
invoice -> invoice.getCustomer() == Customer.ORACLE); 
List<Invoice> trainingInvoices = 
findInvoices(invoices, 
invoice -> invoice.getName().endsWith("Training"));
First-class functions 
● Common Object Oriented concept: Function Object 
● All it means is the ability to use a function just like a regular value 
○ Pass it as argument to a method 
○ Store it in a variable 
● Helps cope with requirement changes
Composing functions 
Functions Composing functions
Composing functions: example 
import java.util.function.Predicate; 
Predicate<Invoice> isFacebookInvoice = this::isFacebookInvoice; 
List<Invoice> facebookAndTraining = 
invoices.stream() 
.filter( isFacebookInvoice.and(this::isTrainingInvoice)) 
.collect(toList()); 
List<Invoice> facebookOrGoogle = 
invoices.stream() 
creating more complex 
functions from building blocks 
.filter( isFacebookInvoice.or(this::isGoogleInvoice)) 
.collect(toList());
Composing functions: why does it work? 
public interface Predicate<T> { 
boolean test(T t); 
default Predicate<T> and(Predicate<? super T> other) { 
Objects.requireNonNull(other); 
return (t) -> test(t) && other.test(t); 
} 
default Predicate<T> or(Predicate<? super T> other) { 
Objects.requireNonNull(other); 
return (t) -> test(t) || other.test(t); 
} 
} 
returns a new 
function that is 
the result of 
composing two 
functions
Creating function pipelines (1) 
public class Email { 
private final String message; 
public Email(String message) { 
this.message = message; 
} 
public Email addHeader() { 
return new Email("Dear Sir/Madam:n" + message); 
} 
public Email checkSpelling() { 
return new Email(message.replaceAll("FTW", "for the win")); 
} 
public Email addSignature() { 
return new Email(message + "nKind regards"); 
} 
}
Creating function pipelines (2) 
import java.util.function.Function; 
Function<Email, Email> addHeader = Email::addHeader; 
Function<Email, Email> processingPipeline = 
addHeader.andThen(Email::checkSpelling) 
.andThen(Email::addSignature); 
andThen andThen 
composing 
functions 
addHeader checkSpelling addSignature 
Email 
{message="Java 
8 FTW!"} 
Email{message='Dear 
Sir/Madam: 
Java 8 for the win! 
Kind regards'}
Creating function pipelines (3) 
import java.util.function.Function; 
Function<Email, Email> addHeader = Email::addHeader; 
Function<Email, Email> processingPipeline = 
addHeader.andThen(Email::addSignature); 
andThen 
composing 
functions 
addHeader addSignature 
Email 
{message="Java 
8 FTW!"} 
Email{message='Dear 
Sir/Madam: 
Java 8 FTW! 
Kind regards'}
First-class Functions 
Currying 
Immutability 
Optional Data Types 
Conclusions
Example: A Conversion Function 
double convert(double amount, double factor, double base) 
{ 
return amount * factor + base; 
} 
// Usage 
double result = convert(10, 1.8, 32); 
assertEquals(result, 50, 0.0);
Using the conversion function 
// Temperatures 
double cInF = convert(10, 1.8, 32); 
double higherTemp = convert(30, 1.8, 32); 
// Currencies 
double dollarsInPounds = convert(10, 0.6, 0); 
// Distance 
double kilometresInMiles = convert(27, 0.62137, 0);
So what’s the problem? 
● Abstraction 
○ How do you write something that operates on different conversion 
functions? 
● Reuse 
○ How do you use the conversion function in different places?
Pragmatic Functional Refactoring with Java 8
Currying the conversion function 
DoubleUnaryOperator convert(double factor, double base) { 
return amount -> amount * factor + base; 
} 
DoubleUnaryOperator convertCtoF = convert(1.8, 32); 
double result = convertCtoF.applyAsDouble(10); 
assertEquals(result, 50, 0.0);
Pragmatic Functional Refactoring with Java 8
Partial Application Examples 
// Temperatures 
DoubleUnaryOperator convertCtoF = convert(1.8, 32); 
// Currencies 
DoubleUnaryOperator convert$to£ = convert(0.6, 0); 
// Distance 
DoubleUnaryOperator convertKmToMi = convert(0.62137, 0);
Summary 
● Currying is about splitting up the arguments of a function. 
● Partial Application is a function “eating” some of its arguments and 
returning a new function
First-class Functions 
Currying 
Immutability 
Optional Data Types 
Conclusions
Mutable objects 
public class TrainJourney { 
private int price; 
private TrainJourney onward; 
public TrainJourney(int price, TrainJourney onward) { 
this.price = price; 
this.onward = onward; 
} 
public int getPrice() { 
return price; 
} 
public TrainJourney getOnward() { 
return onward; 
} 
public void setPrice(int price) { 
this.price = price; 
} 
public void setOnward(TrainJourney onward) { 
this.onward = onward; 
} 
}
Immutable objects 
public class TrainJourneyImmutable { 
private final int price; 
private final TrainJourneyImmutable onward; 
public TrainJourneyImmutable(int price, TrainJourney onward) { 
this.price = price; 
this.onward = onward; 
} 
public int getPrice() { 
return price; 
} 
public TrainJourneyImmutable getOnward() { 
return onward; 
} 
public TrainJourneyImmutable withPrice(int price) { 
return new TrainJourneyImmutable(price, getOnward()); 
} 
public TrainJourneyImmutable withOnward(TrainJourneyImmutable onward) { 
return new TrainJourneyImmutable(getPrice(), onward); 
} 
}
Scenario: be able to link together train 
journeys to form longer journeys.
Pragmatic Functional Refactoring with Java 8
Mutable approach 
public TrainJourney link(TrainJourney start, TrainJourney continuation) { 
if (start == null) { 
return continuation; 
} 
TrainJourney t = start; 
while (t.getOnward() != null) { 
t = t.getOnward(); 
} 
t.setOnward(continuation); 
return start; 
} 
return the continuation journey if 
there is no start journey 
find the last stop in the first journey 
modify it to link to the continuation 
journey
Mutable approach: problem 
TrainJourney firstJourney = link(start, continuation); 
TrainJourney secondJourney = link(start, continuation); 
visit(secondJourney, 
tj -> { System.out.print(tj.price + " - "); }); 
static void visit(TrainJourney journey, Consumer<TrainJourney> c) 
{ 
if (journey != null) { 
c.accept(journey); 
visit(journey.onward, c); 
} 
}
java.lang.StackOverflowError
Pragmatic Functional Refactoring with Java 8
Immutable approach 
public TrainJourneyImmutable link(TrainJourneyImmutable start, 
TrainJourneyImmutable continuation) { 
return start == null ? continuation 
: new TrainJourneyImmutable(start.getPrice(), 
link(start.getOnward(), continuation)); 
}
Related topics 
● Domain Driven Design 
○ Value Classes are Immutable 
● Core Java Improvements 
○ New date & time library in Java 8 has many Immutable Objects 
○ Current Value Types proposal is immutable 
● Tooling 
○ final keyword only bans reassignment 
○ JSR 308 - improved annotation opportunities 
○ Mutability Detector 
○ Findbugs
Immutable objects reduce the scope for bugs.
First-class Functions 
Currying 
Immutability 
Optional Data Types 
Conclusions
Don’t we all love it? 
Exception in thread "main" java.lang.NullPointerException
public String getCarInsuranceName(Person person) { 
return person.getCar().getInsurance().getName(); 
} 
Where’s the NPE?
Defensive checking 
public String getCarInsuranceName(Person person) { 
if (person != null) { 
Car car = person.getCar(); 
if (car != null) { 
Insurance insurance = car.getInsurance(); 
if (insurance != null) { 
return insurance.getName(); 
} 
} 
} 
return "No Insurance"; 
}
Optional 
● Java 8 introduces a new class java.util.Optional<T> 
○ a single-value container 
● Explicit modelling 
○ Immediately clear that its an optional value 
○ better maintainability 
● You need to actively unwrap an Optional 
○ force users to think about the absence case 
○ fewer errors
Updating model 
public class Person { 
private Optional<Car> car; 
public Optional<Car> getCar() { return car; } 
} 
public class Car { 
private Optional<Insurance> insurance; 
public Optional<Insurance> getInsurance() { return insurance; } 
} 
public class Insurance { 
private String name; 
public String getName() { return name; } 
}
Optional.map
Why it doesn’t work? 
Optional<People> optPerson = Optional.ofNullable(person); 
Optional<String> name = 
optPeople.map(Person::getCar) 
.map(Car::getInsurance) 
.map(Insurance::getName); 
returns Optional<Optional<Car>> 
Invalid, the inner Optional object 
doesn’t support the method 
getInsurance! 
public class Person { 
private Optional<Car> car; 
public Optional<Car> getCar() { return car; } 
}
Pragmatic Functional Refactoring with Java 8
Optional.flatMap
Chaining methods with flatMap 
public String getCarInsuranceName(Person person) { 
return Optional.ofNullable(person) 
.flatMap(Person::getCar) 
.flatMap(Car::getInsurance) 
.map(Insurance::getName) 
.orElse("Unknown"); 
} 
default value if the resulting 
Optional is empty
Consistent use of Optional replaces the use of null
First-class Functions 
Currying 
Immutability 
Optional Data Types 
Conclusions
Summary of benefits 
● First-class functions let you cope for requirement changes 
● Currying lets you split the parameters of a function to re-use code logic 
● Immutability reduces the scope for bugs 
● Optional data types lets you reduce null checking boilerplate and 
prevent bugs
Pragmatic Functional Refactoring with Java 8
Training Website: http://java8training.com 
http://manning.com/urma http://tinyurl.com/java8lambdas
Any Questions? 
Richard Warburton 
@richardwarburto 
Raoul-Gabriel Urma 
@raoulUK
Example currying use cases 
● Large factory methods 
○ Partially apply some of the arguments and then pass this factory 
object around. 
● Parser Combinators 
○ many(‘a’) - function which parses a, aa, aaa, etc.
A curry function 
// int -> (int -> int) 
IntFunction<IntUnaryOperator> 
curry(IntBinaryOperator biFunction) { 
return f -> s -> biFunction.applyAsInt(f, s); 
} 
// Usage: 
IntFunction<IntUnaryOperator> add = curry((f, s) -> f + 
s); 
int result = add.apply(1) 
.applyAsInt(2); 
assertEquals(3, result);
Generalised curry function 
// F -> (S -> R) 
<F, S, R> Function<F, Function<S, R>> 
curry(BiFunction<F, S, R> biFunction) { 
return f -> s -> biFunction.apply(f, s); 
}
Ad

More Related Content

What's hot (20)

React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
Katy Slemon
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
Daniel Bryant
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
Kaniska Mandal
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
Mario Fusco
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overview
gourav kottawar
 
Embedding Java code in a Jolie Service
Embedding Java code in a Jolie ServiceEmbedding Java code in a Jolie Service
Embedding Java code in a Jolie Service
JolieLang
 
Running Javascript as a microservice inside of Jolie
Running Javascript as a microservice inside of JolieRunning Javascript as a microservice inside of Jolie
Running Javascript as a microservice inside of Jolie
JolieLang
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Codemotion
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
Christoffer Noring
 
Chat application in java using swing and socket programming.
Chat application in java using swing and socket programming.Chat application in java using swing and socket programming.
Chat application in java using swing and socket programming.
Kuldeep Jain
 
More on Classes and Objects
More on Classes and ObjectsMore on Classes and Objects
More on Classes and Objects
Payel Guria
 
Chekout demistified
Chekout demistifiedChekout demistified
Chekout demistified
Damijan Ćavar
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
BoneyGawande
 
重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1
Chris Huang
 
重構—改善既有程式的設計(chapter 8)part 2
重構—改善既有程式的設計(chapter 8)part 2重構—改善既有程式的設計(chapter 8)part 2
重構—改善既有程式的設計(chapter 8)part 2
Chris Huang
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
Dhaval Dalal
 
Anonymous functions in JavaScript
Anonymous functions in JavaScriptAnonymous functions in JavaScript
Anonymous functions in JavaScript
Mohammed Sazid Al Rashid
 
Angular 2.0 Pipes
Angular 2.0 PipesAngular 2.0 Pipes
Angular 2.0 Pipes
Eyal Vardi
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
Matteo Baglini
 
4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers
PROIDEA
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
Katy Slemon
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
Daniel Bryant
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
Kaniska Mandal
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
Mario Fusco
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overview
gourav kottawar
 
Embedding Java code in a Jolie Service
Embedding Java code in a Jolie ServiceEmbedding Java code in a Jolie Service
Embedding Java code in a Jolie Service
JolieLang
 
Running Javascript as a microservice inside of Jolie
Running Javascript as a microservice inside of JolieRunning Javascript as a microservice inside of Jolie
Running Javascript as a microservice inside of Jolie
JolieLang
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Codemotion
 
Chat application in java using swing and socket programming.
Chat application in java using swing and socket programming.Chat application in java using swing and socket programming.
Chat application in java using swing and socket programming.
Kuldeep Jain
 
More on Classes and Objects
More on Classes and ObjectsMore on Classes and Objects
More on Classes and Objects
Payel Guria
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
BoneyGawande
 
重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1
Chris Huang
 
重構—改善既有程式的設計(chapter 8)part 2
重構—改善既有程式的設計(chapter 8)part 2重構—改善既有程式的設計(chapter 8)part 2
重構—改善既有程式的設計(chapter 8)part 2
Chris Huang
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
Dhaval Dalal
 
Angular 2.0 Pipes
Angular 2.0 PipesAngular 2.0 Pipes
Angular 2.0 Pipes
Eyal Vardi
 
4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers
PROIDEA
 

Viewers also liked (10)

Streams in Java 8
Streams in Java 8Streams in Java 8
Streams in Java 8
Tobias Coetzee
 
Type Annotations in Java 8
Type Annotations in Java 8 Type Annotations in Java 8
Type Annotations in Java 8
FinLingua, Inc.
 
Annotation based null analysis in Eclipse JDT
Annotation based null analysis in Eclipse JDTAnnotation based null analysis in Eclipse JDT
Annotation based null analysis in Eclipse JDT
Eclipse Day India
 
Let if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and moreLet if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and more
Bhakti Mehta
 
Java 8 by example!
Java 8 by example!Java 8 by example!
Java 8 by example!
Mark Harrison
 
50 new things we can do with Java 8
50 new things we can do with Java 850 new things we can do with Java 8
50 new things we can do with Java 8
José Paumard
 
Java SE 8 library design
Java SE 8 library designJava SE 8 library design
Java SE 8 library design
Stephen Colebourne
 
Sailing with Java 8 Streams
Sailing with Java 8 StreamsSailing with Java 8 Streams
Sailing with Java 8 Streams
Ganesh Samarthyam
 
Java SE 8 best practices
Java SE 8 best practicesJava SE 8 best practices
Java SE 8 best practices
Stephen Colebourne
 
Java 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJava 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelization
José Paumard
 
Type Annotations in Java 8
Type Annotations in Java 8 Type Annotations in Java 8
Type Annotations in Java 8
FinLingua, Inc.
 
Annotation based null analysis in Eclipse JDT
Annotation based null analysis in Eclipse JDTAnnotation based null analysis in Eclipse JDT
Annotation based null analysis in Eclipse JDT
Eclipse Day India
 
Let if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and moreLet if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and more
Bhakti Mehta
 
50 new things we can do with Java 8
50 new things we can do with Java 850 new things we can do with Java 8
50 new things we can do with Java 8
José Paumard
 
Java 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJava 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelization
José Paumard
 
Ad

Similar to Pragmatic Functional Refactoring with Java 8 (20)

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
Pavan Chitumalla
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
javatwo2011
 
What is new in java 8 concurrency
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrency
kshanth2101
 
Functional Vaadin talk at OSCON 2014
Functional Vaadin talk at OSCON 2014Functional Vaadin talk at OSCON 2014
Functional Vaadin talk at OSCON 2014
hezamu
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
Chris Weldon
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
Matthieu Aubry
 
laravel resume10 trés résume avec les coses importatnt.pdf
laravel resume10 trés résume avec les coses importatnt.pdflaravel resume10 trés résume avec les coses importatnt.pdf
laravel resume10 trés résume avec les coses importatnt.pdf
rachidtamesna12
 
What is new in sulu 2.0
What is new in sulu 2.0What is new in sulu 2.0
What is new in sulu 2.0
danrot
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
BOSC Tech Labs
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
Christoffer Noring
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
NSCoder Mexico
 
Http Communication in Angular 2.0
Http Communication in Angular 2.0Http Communication in Angular 2.0
Http Communication in Angular 2.0
Eyal Vardi
 
FunctionalInterfaces
FunctionalInterfacesFunctionalInterfaces
FunctionalInterfaces
Ralph Lecessi Incorporated
 
FunctionalInterfaces
FunctionalInterfacesFunctionalInterfaces
FunctionalInterfaces
YourVirtual Class
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
Taha Shakeel
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
Danylenko Max
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
Ignacio Coloma
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
Pavan Chitumalla
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
javatwo2011
 
What is new in java 8 concurrency
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrency
kshanth2101
 
Functional Vaadin talk at OSCON 2014
Functional Vaadin talk at OSCON 2014Functional Vaadin talk at OSCON 2014
Functional Vaadin talk at OSCON 2014
hezamu
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
Matthieu Aubry
 
laravel resume10 trés résume avec les coses importatnt.pdf
laravel resume10 trés résume avec les coses importatnt.pdflaravel resume10 trés résume avec les coses importatnt.pdf
laravel resume10 trés résume avec les coses importatnt.pdf
rachidtamesna12
 
What is new in sulu 2.0
What is new in sulu 2.0What is new in sulu 2.0
What is new in sulu 2.0
danrot
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
BOSC Tech Labs
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
NSCoder Mexico
 
Http Communication in Angular 2.0
Http Communication in Angular 2.0Http Communication in Angular 2.0
Http Communication in Angular 2.0
Eyal Vardi
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
Taha Shakeel
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
Danylenko Max
 
Ad

More from Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
Codemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
Codemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
Codemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Codemotion
 
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
Codemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
Codemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
Codemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Codemotion
 

Pragmatic Functional Refactoring with Java 8

  • 1. Pragmatic Functional Refactoring with Java 8 Raoul-Gabriel Urma (@raoulUK) Richard Warburton (@RichardWarburto)
  • 4. First-class Functions Currying Immutability Optional Data Types Conclusions
  • 5. Step 1: filtering invoices from Oracle public List<Invoice> findInvoicesFromOracle(List<Invoice> invoices) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if( invoice.getCustomer() == Customer.ORACLE) { result.add(invoice); } } return result; }
  • 6. Step 2a: abstracting the customer public List<Invoice> findInvoicesFromCustomer(List<Invoice> invoices, Customer customer) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if( invoice.getCustomer() == customer) { result.add(invoice); } } return result; }
  • 7. Step 2b: abstracting the name public List<Invoice> findInvoicesEndingWith(List<Invoice> invoices, String suffix) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if( invoice.getName().endsWith(suffix)) { result.add(invoice); } } return result; }
  • 8. Step 3: messy code-reuse! private List<Invoice> findInvoices(List<Invoice> invoices, Customer customer, String suffix, boolean flag) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if(( flag && invoice.getCustomer() == customer) || (!flag && invoice.getName().endsWith(suffix))) { result.add(invoice); } } return result; }
  • 9. Step 4a: modeling the filtering criterion public interface Predicate<T> { boolean test(T t); } Invoice boolean Predicate<Invoice>
  • 10. Step 4b: using different criterion with objects private List<Invoice> findInvoices(List<Invoice> invoices, Predicate<Invoice> p) { List<Invoice> result = new ArrayList<>(); for(Invoice invoice: invoices) { if( p.test(invoice)) { result.add(invoice); } } return result; }
  • 11. Step 4b: using different criterion with objects List<Invoice> specificInvoices = findInvoices(invoices, new FacebookTraining()); class FacebookTraining implements Predicate<Invoice> { @Override public boolean test(Invoice invoice) { return invoice.getCustomer() == Customer.FACEBOOK && invoice.getName().endsWith("Training"); } }
  • 12. Step 5: method references public boolean isOracleInvoice(Invoice invoice) { return invoice.getCustomer() == Customer.ORACLE; } public boolean isTrainingInvoice(Invoice invoice) { return invoice.getName().endsWith("Training"); } List<Invoice> oracleInvoices = findInvoices(invoices, this::isOracleInvoice); List<Invoice> trainingInvoices = findInvoices(invoices, this::isTrainingInvoice); method references
  • 13. Step 6: lambdas List<Invoice> oracleInvoices = findInvoices(invoices, invoice -> invoice.getCustomer() == Customer.ORACLE); List<Invoice> trainingInvoices = findInvoices(invoices, invoice -> invoice.getName().endsWith("Training"));
  • 14. First-class functions ● Common Object Oriented concept: Function Object ● All it means is the ability to use a function just like a regular value ○ Pass it as argument to a method ○ Store it in a variable ● Helps cope with requirement changes
  • 15. Composing functions Functions Composing functions
  • 16. Composing functions: example import java.util.function.Predicate; Predicate<Invoice> isFacebookInvoice = this::isFacebookInvoice; List<Invoice> facebookAndTraining = invoices.stream() .filter( isFacebookInvoice.and(this::isTrainingInvoice)) .collect(toList()); List<Invoice> facebookOrGoogle = invoices.stream() creating more complex functions from building blocks .filter( isFacebookInvoice.or(this::isGoogleInvoice)) .collect(toList());
  • 17. Composing functions: why does it work? public interface Predicate<T> { boolean test(T t); default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } } returns a new function that is the result of composing two functions
  • 18. Creating function pipelines (1) public class Email { private final String message; public Email(String message) { this.message = message; } public Email addHeader() { return new Email("Dear Sir/Madam:n" + message); } public Email checkSpelling() { return new Email(message.replaceAll("FTW", "for the win")); } public Email addSignature() { return new Email(message + "nKind regards"); } }
  • 19. Creating function pipelines (2) import java.util.function.Function; Function<Email, Email> addHeader = Email::addHeader; Function<Email, Email> processingPipeline = addHeader.andThen(Email::checkSpelling) .andThen(Email::addSignature); andThen andThen composing functions addHeader checkSpelling addSignature Email {message="Java 8 FTW!"} Email{message='Dear Sir/Madam: Java 8 for the win! Kind regards'}
  • 20. Creating function pipelines (3) import java.util.function.Function; Function<Email, Email> addHeader = Email::addHeader; Function<Email, Email> processingPipeline = addHeader.andThen(Email::addSignature); andThen composing functions addHeader addSignature Email {message="Java 8 FTW!"} Email{message='Dear Sir/Madam: Java 8 FTW! Kind regards'}
  • 21. First-class Functions Currying Immutability Optional Data Types Conclusions
  • 22. Example: A Conversion Function double convert(double amount, double factor, double base) { return amount * factor + base; } // Usage double result = convert(10, 1.8, 32); assertEquals(result, 50, 0.0);
  • 23. Using the conversion function // Temperatures double cInF = convert(10, 1.8, 32); double higherTemp = convert(30, 1.8, 32); // Currencies double dollarsInPounds = convert(10, 0.6, 0); // Distance double kilometresInMiles = convert(27, 0.62137, 0);
  • 24. So what’s the problem? ● Abstraction ○ How do you write something that operates on different conversion functions? ● Reuse ○ How do you use the conversion function in different places?
  • 26. Currying the conversion function DoubleUnaryOperator convert(double factor, double base) { return amount -> amount * factor + base; } DoubleUnaryOperator convertCtoF = convert(1.8, 32); double result = convertCtoF.applyAsDouble(10); assertEquals(result, 50, 0.0);
  • 28. Partial Application Examples // Temperatures DoubleUnaryOperator convertCtoF = convert(1.8, 32); // Currencies DoubleUnaryOperator convert$to£ = convert(0.6, 0); // Distance DoubleUnaryOperator convertKmToMi = convert(0.62137, 0);
  • 29. Summary ● Currying is about splitting up the arguments of a function. ● Partial Application is a function “eating” some of its arguments and returning a new function
  • 30. First-class Functions Currying Immutability Optional Data Types Conclusions
  • 31. Mutable objects public class TrainJourney { private int price; private TrainJourney onward; public TrainJourney(int price, TrainJourney onward) { this.price = price; this.onward = onward; } public int getPrice() { return price; } public TrainJourney getOnward() { return onward; } public void setPrice(int price) { this.price = price; } public void setOnward(TrainJourney onward) { this.onward = onward; } }
  • 32. Immutable objects public class TrainJourneyImmutable { private final int price; private final TrainJourneyImmutable onward; public TrainJourneyImmutable(int price, TrainJourney onward) { this.price = price; this.onward = onward; } public int getPrice() { return price; } public TrainJourneyImmutable getOnward() { return onward; } public TrainJourneyImmutable withPrice(int price) { return new TrainJourneyImmutable(price, getOnward()); } public TrainJourneyImmutable withOnward(TrainJourneyImmutable onward) { return new TrainJourneyImmutable(getPrice(), onward); } }
  • 33. Scenario: be able to link together train journeys to form longer journeys.
  • 35. Mutable approach public TrainJourney link(TrainJourney start, TrainJourney continuation) { if (start == null) { return continuation; } TrainJourney t = start; while (t.getOnward() != null) { t = t.getOnward(); } t.setOnward(continuation); return start; } return the continuation journey if there is no start journey find the last stop in the first journey modify it to link to the continuation journey
  • 36. Mutable approach: problem TrainJourney firstJourney = link(start, continuation); TrainJourney secondJourney = link(start, continuation); visit(secondJourney, tj -> { System.out.print(tj.price + " - "); }); static void visit(TrainJourney journey, Consumer<TrainJourney> c) { if (journey != null) { c.accept(journey); visit(journey.onward, c); } }
  • 39. Immutable approach public TrainJourneyImmutable link(TrainJourneyImmutable start, TrainJourneyImmutable continuation) { return start == null ? continuation : new TrainJourneyImmutable(start.getPrice(), link(start.getOnward(), continuation)); }
  • 40. Related topics ● Domain Driven Design ○ Value Classes are Immutable ● Core Java Improvements ○ New date & time library in Java 8 has many Immutable Objects ○ Current Value Types proposal is immutable ● Tooling ○ final keyword only bans reassignment ○ JSR 308 - improved annotation opportunities ○ Mutability Detector ○ Findbugs
  • 41. Immutable objects reduce the scope for bugs.
  • 42. First-class Functions Currying Immutability Optional Data Types Conclusions
  • 43. Don’t we all love it? Exception in thread "main" java.lang.NullPointerException
  • 44. public String getCarInsuranceName(Person person) { return person.getCar().getInsurance().getName(); } Where’s the NPE?
  • 45. Defensive checking public String getCarInsuranceName(Person person) { if (person != null) { Car car = person.getCar(); if (car != null) { Insurance insurance = car.getInsurance(); if (insurance != null) { return insurance.getName(); } } } return "No Insurance"; }
  • 46. Optional ● Java 8 introduces a new class java.util.Optional<T> ○ a single-value container ● Explicit modelling ○ Immediately clear that its an optional value ○ better maintainability ● You need to actively unwrap an Optional ○ force users to think about the absence case ○ fewer errors
  • 47. Updating model public class Person { private Optional<Car> car; public Optional<Car> getCar() { return car; } } public class Car { private Optional<Insurance> insurance; public Optional<Insurance> getInsurance() { return insurance; } } public class Insurance { private String name; public String getName() { return name; } }
  • 49. Why it doesn’t work? Optional<People> optPerson = Optional.ofNullable(person); Optional<String> name = optPeople.map(Person::getCar) .map(Car::getInsurance) .map(Insurance::getName); returns Optional<Optional<Car>> Invalid, the inner Optional object doesn’t support the method getInsurance! public class Person { private Optional<Car> car; public Optional<Car> getCar() { return car; } }
  • 52. Chaining methods with flatMap public String getCarInsuranceName(Person person) { return Optional.ofNullable(person) .flatMap(Person::getCar) .flatMap(Car::getInsurance) .map(Insurance::getName) .orElse("Unknown"); } default value if the resulting Optional is empty
  • 53. Consistent use of Optional replaces the use of null
  • 54. First-class Functions Currying Immutability Optional Data Types Conclusions
  • 55. Summary of benefits ● First-class functions let you cope for requirement changes ● Currying lets you split the parameters of a function to re-use code logic ● Immutability reduces the scope for bugs ● Optional data types lets you reduce null checking boilerplate and prevent bugs
  • 57. Training Website: http://java8training.com http://manning.com/urma http://tinyurl.com/java8lambdas
  • 58. Any Questions? Richard Warburton @richardwarburto Raoul-Gabriel Urma @raoulUK
  • 59. Example currying use cases ● Large factory methods ○ Partially apply some of the arguments and then pass this factory object around. ● Parser Combinators ○ many(‘a’) - function which parses a, aa, aaa, etc.
  • 60. A curry function // int -> (int -> int) IntFunction<IntUnaryOperator> curry(IntBinaryOperator biFunction) { return f -> s -> biFunction.applyAsInt(f, s); } // Usage: IntFunction<IntUnaryOperator> add = curry((f, s) -> f + s); int result = add.apply(1) .applyAsInt(2); assertEquals(3, result);
  • 61. Generalised curry function // F -> (S -> R) <F, S, R> Function<F, Function<S, R>> curry(BiFunction<F, S, R> biFunction) { return f -> s -> biFunction.apply(f, s); }