KEMBAR78
Lambda and Stream Master class - part 1 | PDF
#Devoxx
Java Lambda Stream
Master Class – Part 1
@StuartMarks @JosePaumard
#LambdaHOL#Devoxx
Master Class?
Did you bring your laptop?
#LambdaHOL#Devoxx
Yes you did!
What about:
- 10-15mn of explaination
- 3-5mn of time to solve the exercice
- ~5mn to show a solution
#LambdaHOL#Devoxx
No you didn’t!
What about:
- 10-15mn of explaination
- 3-5mn to show a first example
- 3-5mn to show a second example
#LambdaHOL#Devoxx
The LambdaHOL
8 test classes, with 80 exercises to complete
- Lambda, functionnal interfaces
- Comparators
- Streams, Collectors
- Some challenges at the end
- Updated regularly
With solutions!
#LambdaHOL#Devoxx
The LambdaHOL
You can find it here
https://github.com/stuart-marks/LambdaHOLv2
#LambdaHOL#Devoxx
Agenda
1st part: API Design with lambdas and
Functional interfaces
2nd part: Streams, reductions, collectors
#LambdaHOL#Devoxx
API Design with lambdas
Chaining lambdas with default methods
- Consumer interface
- Predicate interface
Composing lambdas
- Comparator interface
Partial Application
- Currency converter example
#LambdaHOL#Devoxx
Stuart Marks
JDK Core Libraries Developer
Java Plaform Group, Oracle
Twitter: @stuartmarks
#LambdaHOL#Devoxx
@JosePaumard
https://www.youtube.com/user/JPaumard
https://www.slideshare.net/jpaumard
https://github.com/JosePaumard
#Devoxx #LambdaHOL
Questions?
#LambdaHOL
#LambdaHOL#Devoxx
For today
The starting point is here:
https://github.com/JosePaumard/lambda-master-class-part1
#Devoxx #LambdaHOL
A Few Words on Functional
Interfaces
#LambdaHOL#Devoxx
Functional interfaces
A functional interface is:
▪ An interface
▪ With one abstract method
▪ Methods from Object do not count
▪ May be annotated with @FunctionalInterface
#LambdaHOL#Devoxx
Functional interfaces
A functional interface can be implemented
with a lambda!
Comparator<String> comparator = new Comparator<String>() {
public int compareTo(String s1, String s2) {
return Integer.compare(s1.length(), s2.length()) ;
}
}
Comparator<String> comparator =
(String s1, String s2) ->
Integer.compare(s1.length(), s2.length()) ;
#Devoxx #LambdaHOL
Consumer
#LambdaHOL#Devoxx
1st example
A consumer that clears a string builder
@Test
public void consumer_1() {
Consumer<List<String>> consumer = null; // TODO
List<String> list =
new ArrayList<>(Arrays.asList("a", "b", "c"));
consumer.accept(list);
assertThat(list).isEmpty();
}
#LambdaHOL#Devoxx
2nd example
A consumer that calls two Consumers
@Test
public void consumer_2() {
Consumer<List<String>> c1 = list -> list.add("first");
Consumer<List<String>> c2 = list -> list.add("second");
Consumer<List<String>> consumer; // TODO
List<String> list =
new ArrayList<>(Arrays.asList("a", "b", "c"));
consumer.accept(list);
assertThat(list).containsExactly("a", "b", "c", "first", "second");
}
#Devoxx #LambdaHOL
Predicate
#LambdaHOL#Devoxx
1st example
A predicate that negates another predicate
@Test
public void predicate_1() {
Predicate<String> predicate = s -> s.isEmpty();
Predicate<String> notPredicate; // TODO
assertThat(notPredicate.test("")).isFalse();
assertThat(notPredicate.test("Not empty!")).isTrue();
}
#LambdaHOL#Devoxx
2nd example
A predicate that is true if a string is non null
and non empty
@Test
public void predicate_2() {
Predicate<String> p1 = s -> s != null;
Predicate<String> p2 = s -> s.isEmpty();
Predicate<String> p3; // TODO
assertThat(p3.test("")).isFalse();
assertThat(p3.test(null)).isFalse();
assertThat(p3.test("Not empty!")).isTrue();
}
#LambdaHOL#Devoxx
3rd example
How to design a xOr() method on Predicate?
@Test
public void predicate_3() {
Predicate<String> p1 = s -> s.length() == 4;
Predicate<String> p2 = s -> s.startsWith("J");
Predicate<String> p3; // TODO
assertThat(p3.test("True")).isTrue();
assertThat(p3.test("Julia")).isTrue();
assertThat(p3.test("Java")).isFalse();
}
#Devoxx #LambdaHOL
Comparator
#LambdaHOL#Devoxx
A first example
What is this code doing?
Comparator<Person> cmp = new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.getLastName().compareTo(p2.getLastName());
}
};
#LambdaHOL#Devoxx
A first example
What is this code doing?
Comparator<Person> cmp = new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
int cmp = p1.getLastName().compareTo(p2.getLastName());
if (cmp == 0) {
return p1.getFirstName().compareTo(p2.getFirstName());
} else {
return cmp;
}
}
};
#LambdaHOL#Devoxx
A first example
What is this code doing?Comparator<Person> cmp = new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
int cmp = p1.getLastName().compareTo(p2.getLastName());
if (cmp == 0) {
cmp = p1.getFirstName().compareTo(p2.getLastName());
if (cmp == 0) {
return Integer.compare(p1.getAge(), p2.getAge());
} else {
return cmp;
}
} else {
return cmp;
}
}
};
#LambdaHOL#Devoxx
A first example
What is this code doing?Comparator<Person> cmp = new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
int cmp = p1.getLastName().compareTo(p2.getLastName());
if (cmp == 0) {
cmp = p1.getFirstName().compareTo(p2.getFirstName());
if (cmp == 0) {
return Integer.compare(p1.getAge(), p2.getAge());
} else {
return cmp;
}
} else {
return cmp;
}
}
};
#LambdaHOL#Devoxx
A first example
What is this code doing?
Comparator<Person> cmp = Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.thenComparing(Person::getAge);
#LambdaHOL#Devoxx
1st example
A comparator that puts null values at the end
Person michael = new Person("Michael", "Jackson", 51);
Person rod = new Person("Rod", "Stewart", 71);
Person paul = new Person("Paul", "McCartney", 74);
Person mick = new Person("Mick", "Jagger", 73);
Person jermaine = new Person("Jermaine", "Jackson", 61);
@Test
public void comparator_1() {
Comparator<Person> cmp = null; // TODO
assertThat(cmp.compare(michael, rod)).isLessThan(0);
assertThat(cmp.compare(paul, paul)).isEqualTo(0);
assertThat(cmp.compare(michael, jermaine)).isGreaterThan(0);
assertThat(cmp.compare(mick, null)).isLessThan(0);
assertThat(cmp.compare(null, mick)).isGreaterThan(0);
}
#Devoxx #LambdaHOL
API Design
#LambdaHOL#Devoxx
A Currency Converter
Given the following data…
Date=2018/11/05
EUR=1
AUD=1.58125
BRL=4.20735
NOK=9.51682
GBP=0.87749
PLN=4.30044
CAD=1.49181
RUB=75.25596
#LambdaHOL#Devoxx
A Currency Converter
… write the following currency converter:
LocalDate date = ...;
CurrencyConverter plnToAud =
CurrencyConverter.of(date)
.from("PLN")
.to("AUD");
float pln = ...;
float aud = plnToAud.convert(pln);
#LambdaHOL#Devoxx
A Validator
Given the following bean
public class Person {
private String lastName ;
private int age ;
// getters, setters, constructeurs
}
#LambdaHOL#Devoxx
A Validator
Implement the following pattern
If the user is not valid: get() throws an exception, with all
the exceptions of each validator in the suppressed
exceptions
Validator<Person> validator = Validator.
.firstValidate(p -> p.getName() == null, "name is null")
.thenValidate(p -> p.getAge() < 0, "age is negative")
.thenValidate(p -> p.getAge() > 150, "age is greater than
150");
person = validator.validate(person).get();
#LambdaHOL#Devoxx
A Validator
If the user is not valid: get() throws an exception, with all
the exceptions of each validator in the suppressed
exceptions
Validator<Person> validator =
Validator
.firstValidate(p -> p.getName() == null, "name is null")
.thenValidate(p -> p.getAge() < 0, "age is negative")
.thenValidate(p -> p.getAge() > 150, "age is greater than 150");
person = validator.validate(person).get();
#Devoxx
Don’t miss the 2nd day:
1) More functional
programming!
2) Stream, reduction
3) Collectors
Day break!
#Devoxx
Java Lambda Stream
Master Class – Part 2
@StuartMarks @JosePaumard
#Devoxx #LambdaHOL
Map Filter Reduce
#Devoxx #LambdaHOL
Advanced Reduction
#Devoxx
Come back for the last part!
1) Collectors
2) Challenges
Coffee break!
#Devoxx #LambdaHOL
Collectors
#Devoxx #LambdaHOL
Challenges
#Devoxx
Questions?
@StuartMarks @JosePaumard
#LambdaHOL
https://github.com/JosePaumard/lambda-master-class-part1
https://github.com/JosePaumard/lambda-master-class-part2

Lambda and Stream Master class - part 1