SlideShare a Scribd company logo
1 of 302
Download to read offline
@JosePaumard 
#J1LBDS 
Autumn Collections 
From Iterable to Lambdas, Streams and Collectors
@JosePaumard 
#J1LBDS
@JosePaumard 
#J1LBDS 
Published 
November 10, 1994
@JosePaumard 
#J1LBDS 
Still available hardover, paperback, multimedia CD 
Published 
November 10, 1994
#J1LBDS 
@JosePaumard 
Why were they introduced ?
#J1LBDS 
@JosePaumard 
Why were they introduced ? 
How will they change the way we build applications ?
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard 
Questions ? 
#J1LBDS
#J1LBDS 
@JosePaumard 
Let’s introduce the lambdas
#J1LBDS 
@JosePaumard 
Let’s introduce the lambdas 
on a simple example
#J1LBDS 
@JosePaumard 
A very simple example 
public class Person { 
private String name ; 
private int age ; 
// constructors 
// getters / setters 
} 
List<Person> list = new ArrayList<>() ; 
A plain old bean… 
… and a good old list
#J1LBDS 
@JosePaumard 
int sum = 0 ; 
// I need a default value in case 
// the list is empty 
int average = 0 ; 
for (Person person : list) { 
sum += person.getAge() ; 
} 
if (!list.isEmpty()) { 
average = sum / list.size() ; 
} 
Average of the ages
#J1LBDS 
@JosePaumard 
int sum = 0 ; 
int n = 0 ; 
int average = 0 ; 
for (Person person : list) { 
if (person.getAge() > 20) { 
n++ ; 
sum += person.getAge() ; 
} 
} 
if (n > 0) { 
average = sum / n ; 
} 
Trickier : average of the ages of people older than 20
#J1LBDS 
@JosePaumard 
Trickier : average of the ages of people older than 20 
« imperative programming » 
int sum = 0 ; 
int n = 0 ; 
int average = 0 ; 
for (Person person : list) { 
if (person.getAge() > 20) { 
n++ ; 
sum += person.getAge() ; 
} 
} 
if (n > 0) { 
average = sum / n ; 
}
#J1LBDS 
@JosePaumard 
select avg(age) 
from Person 
where age > 20 
… it does not have to be like that ! 
This is a description of the result
#J1LBDS 
@JosePaumard 
… it does not have to be like that ! 
This is a description of the result 
In that case, the DB server is free to compute the result the way it sees fit 
© SQL language, 1974 
select avg(age) 
from Person 
where age > 20
#J1LBDS 
@JosePaumard 
Person 
age 
age > 20 
sum 
1st step : mapping 
map
#J1LBDS 
@JosePaumard 
Person 
age 
age > 20 
sum 
1st step : mapping 
Mapping : 
-takes a list of a given type 
-gives another list of a different type 
-same number of elements 
map
#J1LBDS 
@JosePaumard 
Person 
age 
age > 20 
sum 
2nd step : filtering 
filter 
map
#J1LBDS 
@JosePaumard 
Person 
age 
age > 20 
sum 
2nd step : filtering 
Filtering : 
-takes a list of a given type 
-gives another list of a the same type 
-less elements 
filter 
map
#J1LBDS 
@JosePaumard 
Person 
age 
age > 20 
sum 
3rd step : reduction 
reduce 
filter 
map
#J1LBDS 
@JosePaumard 
Person 
age 
age > 20 
sum 
3rd step : reduction 
Reduction : agregation of all the elements in a single one 
Ex : average, sum, min, max, etc… 
reduce 
filter 
map
#J1LBDS 
@JosePaumard 
How can I model that ?
#J1LBDS 
@JosePaumard 
The JDK 7 way 
Create an interface to model the mapper… 
public interface Mapper<T, V> { 
public V map(T t) ; 
}
#J1LBDS 
@JosePaumard 
Mapper<Person, Integer> mapper = new Mapper<Person, Integer>() { 
public Integer map(Person p) { 
return p.getAge() ; 
} 
} 
The JDK 7 way 
… and create an implementation 
public interface Mapper<T, V> { 
public V map(T t) ; 
}
#J1LBDS 
@JosePaumard 
Predicate<Integer> predicate = new Predicate<Integer>() { 
public boolean filter(Integer age) { 
return age > 20 ; 
} 
} 
The JDK 7 way 
We can do the same for filtering 
public interface Predicate<T> { 
public boolean filter(T t) ; 
}
#J1LBDS 
@JosePaumard 
Reducer<Integer> reduction = new Reducer<Integer>() { 
public Integer reduce(Integer i1, Integer i2) { 
return i1 + i2 ; 
} 
} 
The JDK 7 way 
And for the reduction 
public interface Reducer<T> { 
public T reduce(T t1, T t2) ; 
}
#J1LBDS 
@JosePaumard 
The JDK 7 way 
So the whole map / filter / reduce looks like this 
1)Create 3 interfaces 
public interface Mapper<T, V> { 
public V map(T t) ; 
} 
public interface Predicate<T> { 
public boolean filter(T t) ; 
} 
public interface Reducer<T> { 
public T reduce(T t1, T t2) ; 
}
#J1LBDS 
@JosePaumard 
The JDK 7 way 
So the whole map / filter / reduce looks like this 
1)Create 3 interfaces 
2)Apply the pattern 
List<Person> persons = ... ; int sum = persons.map( new Mapper<Person, Integer>() { public Integer map(Person p) { return p.getAge() ; } }) .filter( new Filter<Integer>() { public boolean filter(Integer age) { return age > 20 ; } }) .reduce(0, new Reducer<Integer>() { public Integer reduce(Integer i1, Integer i2) { return i1 + i2 ; } } }) ;
#J1LBDS 
@JosePaumard 
The JDK 7 way 
So the whole map / filter / reduce looks like this 
1)Create 3 interfaces 
2)Apply the pattern 
List<Person> persons = ... ; 
int sum = 
persons.map( 
new Mapper<Person, Integer>() { 
public Integer map(Person p) { 
return p.getAge() ; 
} 
}) 
.filter( 
new Filter<Integer>() { 
public boolean filter(Integer age) { 
return age > 20 ; 
} 
}) 
.reduce(0, 
new Reducer<Integer>() { 
public Integer reduce(Integer i1, Integer i2) { 
return i1 + i2 ; 
} 
} 
}) ;
#J1LBDS 
@JosePaumard 
The JDK 8 way
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
mapper = new Mapper<Person, Integer>() { 
public Integer map(Person person) { 
return person.getAge() ; 
} 
}
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
mapper = new Mapper<Person, Integer>() { 
public Integer map(Person person) { // 1 method 
return person.getAge() ; 
} 
}
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
mapper = new Mapper<Person, Integer>() { 
public Integer map(Person person) { // 1 method 
return person.getAge() ; 
} 
} 
mapper = (Person person) 
we take a person p
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
mapper = new Mapper<Person, Integer>() { 
public Integer map(Person person) { // 1 method 
return person.getAge() ; 
} 
} 
mapper = (Person person) -> 
and then …
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
mapper = new Mapper<Person, Integer>() { 
public Integer map(Person person) { // 1 method 
return person.getAge() ; 
} 
} 
mapper = (Person person) -> person.getAge() ; 
… return the age of person
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
mapper = new Mapper<Person, Integer>() { 
public Integer map(Person person) { // 1 method 
return person.getAge() ; 
} 
} 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
Let’s rewrite our mapper 
The compiler can recognize this as an implementation of Mapper 
mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } } 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
Some corner cases
#J1LBDS 
@JosePaumard 
What if … 
… there is more than one statement ? 
The return has to be explicit 
mapper = (Person person) -> { 
System.out.println("Mapping " + person) ; 
return person.getAge() ; 
}
#J1LBDS 
@JosePaumard 
What if … 
…I have no return value ? 
consumer = (Person person) -> p.setAge(p.getAge() + 1) ;
#J1LBDS 
@JosePaumard 
…I have more than one argument ? 
Or : 
reducer = (int i1, int i2) -> { 
return i1 + i2 ; 
} 
What if … 
reducer = (int i1, int i2) -> i1 + i2 ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
How can the compiler recognize the implementation of Mapper ? 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
How can the compiler recognize the implementation of Mapper ? 
1)mapper is of type Mapper 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
How can the compiler recognize the implementation of Mapper ? 
1)mapper is of type Mapper 
2)There is only one method in Mapper 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
How can the compiler recognize the implementation of Mapper ? 
1)mapper is of type Mapper 
2)There is only one method in Mapper 
3)Both the parameters and the return types are compatible 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
How can the compiler recognize the implementation of Mapper ? 
1)mapper is of type Mapper 
2)There is only one method in Mapper 
3)Both the parameters and the return types are compatible 
4)Thrown exceptions (if any are compatible) 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
The JDK 8 way 
How can the compiler recognize the implementation of Mapper ? 
1)mapper is of type Mapper 
2)There is only one method in Mapper 
3)Both the parameters and the return types are compatible 
4)Thrown exceptions (if any are compatible) 
mapper = (Person person) -> person.getAge() ;
#J1LBDS 
@JosePaumard 
More lambdas 
Writing more lambdas becomes natural : 
mapper = (Person person) -> person.getAge() ; // mapper 
filter = (int age) -> age > 20 ; // filter 
reducer = (int i1, int i2) -> i1 + i2 ; // reducer
#J1LBDS 
@JosePaumard 
More lambdas 
And most of the time, the compiler understands this : 
The « parameter types » can be omitted 
mapper = person -> person.getAge() ; // mapper filter = age -> age > 20 ; // filter reducer = (i1, i2) -> i1 + i2 ; // reducer
#J1LBDS 
@JosePaumard 
Just a remark on the reduction 
How does it really work ?
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard 
Reduction 
Examples : 
Reducer r1 = (i1, i2) -> i1 + i2 ; // Ok
#J1LBDS 
@JosePaumard 
Reduction 
Examples : 
Reducer r1 = (i1, i2) -> i1 + i2 ; // Ok 
Reducer r2 = (i1, i2) -> i1*i1 + i2*i2 ; // Oooops 
Reducer r3 = (i1, i2) -> (i1 + i2)*(i1 + i2) ; // Aaaargh
#J1LBDS 
@JosePaumard 
Reduction 
Examples : 
Caveat : 
the result is always reproductible in serial 
it’s not in parallel 
Reducer r1 = (i1, i2) -> i1 + i2 ; // Ok 
Reducer r2 = (i1, i2) -> i1*i1 + i2*i2 ; // Oooops 
Reducer r3 = (i1, i2) -> (i1 + i2)*(i1 + i2) ; // Aaaargh 
Reducer r4 = (i1, i2) -> (i1 + i2) / 2 ; // Ouch !!
#J1LBDS 
@JosePaumard 
So far 
A lambda expression is an alternative to write instances of anonymous inner classes
#J1LBDS 
@JosePaumard 
Other syntaxes 
Very often one writes 
mapper = person -> person.getAge() ;
#J1LBDS 
@JosePaumard 
Other syntaxes 
Very often one writes 
But this syntax is also possible : 
« method reference » 
mapper = Person::getAge ; // non static method 
mapper = person -> person.getAge() ;
#J1LBDS 
@JosePaumard 
Other example : 
Or : 
sum = (i1, i2) -> i1 + i2 ; 
sum = Integer::sum ; // static method, new ! 
Other syntaxes 
max = (i1, i2) -> i1 > i2 ? i1 : i2 ; 
max = Integer::max ; // static method, new !
#J1LBDS 
@JosePaumard 
Other syntaxes 
Other example : 
toLower = String::toLowerCase ; 
// !!!! NO NO NO !!!! 
toLowerFR = String::toLowerCase(Locale.FRANCE) ;
#J1LBDS 
@JosePaumard 
More on the lambdas
#J1LBDS 
@JosePaumard 
3 Questions about lambdas : 
What model for a lambda ?
#J1LBDS 
@JosePaumard 
3 Questions about lambdas : 
What model for a lambda ? 
Can I put a lambda in a variable ?
#J1LBDS 
@JosePaumard 
3 Questions about lambdas : 
What model for a lambda ? 
Can I put a lambda in a variable ? 
Is a lambda an object ?
#J1LBDS 
@JosePaumard 
Modelization 
A lambda is an instance of a « functional interface » 
@FunctionalInterface 
public interface Consumer<T> { 
public void accept(T t) ; 
}
#J1LBDS 
@JosePaumard 
Modelization 
A lambda is an instance of a « functional interface » 
-only one abstract method (methods from Object dont count) 
-can be annotated by @FunctionalInterface (optional) 
@FunctionalInterface 
public interface Consumer<T> { 
public void accept(T t) ; 
}
#J1LBDS 
@JosePaumard 
Putting a lambda in a variable 
Example of a consumer 
So : 
Consumer<String> c = new Consumer<String>() { 
@Override 
public void accept(String s) { 
System.out.println(s) ; 
} 
} ; 
Consumer<String> c = s -> System.out.println(s) ;
#J1LBDS 
@JosePaumard 
Putting a lambda in a variable 
Example of a consumer 
So : 
Consumer<String> c = new Consumer<String>() { 
@Override 
public void accept(String s) { 
System.out.println(s) ; 
} 
} ; 
Consumer<String> c = System.out::println ;
#J1LBDS 
@JosePaumard 
Questions : 
What model for a lambda ? 
answer : with a functional interface 
Can I put a lambda in a variable ? 
answer : yes 
Is a lambda an object ?
#J1LBDS 
@JosePaumard 
Is a lambda an objet ? 
Let’s play the game of 7 errors (with only 1 error) 
Consumer<String> c = new Consumer<String>() { 
@Override 
public void accept(String s) { 
System.out.println(s) ; 
} 
} ; 
Consumer<String> c = s -> System.out.println(s) ;
#J1LBDS 
@JosePaumard 
Is a lambda an objet ? 
Let’s play the game of 7 errors (with only 1 error) 
Consumer<String> c = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s) ; } } ; 
Consumer<String> c = s -> System.out.println(s) ;
#J1LBDS 
@JosePaumard 
Questions : 
What model for a lambda ? 
answer : with a functionnal interface 
Can I put a lambda in a variable ? 
answer : yes 
Is a lambda an object ? 
answer : no
#J1LBDS 
@JosePaumard 
Plenty of lambdas : 
java.util.function
#J1LBDS 
@JosePaumard 
Java.util.functions 
This new package holds the functionnal interfaces 
There are 43 of them
#J1LBDS 
@JosePaumard 
Java.util.functions 
Supplier : alone in its kind 
Consumer / BiConsumer 
Function / BiFunction (UnaryOperator / BinaryOperator) 
Predicate / BiPredicate 
Plus the primitive types versions
#J1LBDS 
@JosePaumard 
Supplier 
A supplier supplies an object 
public interface Supplier<T> { 
T get() ; 
}
#J1LBDS 
@JosePaumard 
Consumer 
A consumer just … accepts an object 
public interface Consumer<T> { 
void accept(T t) ; 
}
#J1LBDS 
@JosePaumard 
Function 
A function takes an object and returns another one 
Can be chained and / or composed 
public interface Function<T, R> { 
R apply(T t) ; 
}
#J1LBDS 
@JosePaumard 
Predicate 
A Predicate takes an object and returns a boolean 
Can be negated, composed with and / or 
public interface Predicate<T> { 
boolean test(T t) ; 
}
#J1LBDS 
@JosePaumard 
Back to the 
map / filter / reduce 
pattern
#J1LBDS 
@JosePaumard 
The JDK 7 way 
How to apply map / filter / reduce 
to List<Person> ?
#J1LBDS 
@JosePaumard 
The JDK 7 way 
How to apply map / filter / reduce 
to List<Person> ? 
The legal way is to iterate over the elements 
and apply the pattern
#J1LBDS 
@JosePaumard 
The JDK 7 way 
How to apply map / filter / reduce 
to List<Person> ? 
The legal way is to iterate over the elements 
and apply the pattern 
One can create a helper method
#J1LBDS 
@JosePaumard 
Applying map to a List 
With a helper method, JDK 7 
List<Person> persons = new ArrayList<>() ; 
List<Integer> ages = // ages is a new list 
Lists.map( 
persons, 
new Mapper<Person, Integer>() { 
public Integer map(Person p) { 
return p.getAge() ; 
} 
} 
) ;
#J1LBDS 
@JosePaumard 
Applying map to a List 
With a helper method, JDK 8 & lambdas 
List<Person> persons = new ArrayList<>() ; 
List<Integer> ages = 
Lists.map( 
persons, 
person -> person.getAge() 
) ;
#J1LBDS 
@JosePaumard 
Applying map to a List 
With a helper method, JDK 8 & lambdas 
List<Person> persons = new ArrayList<>() ; 
List<Integer> ages = 
Lists.map( 
persons, 
Person::getAge 
) ;
#J1LBDS 
@JosePaumard 
Putting things together 
The map / filter / reduce pattern would look like this 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
The map / filter / reduce pattern would look like this 
The idea is to push lambdas to the API, and let it apply them on its content 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
The map / filter / reduce pattern would look like this 
Pro : the API can be optimized without touching the code : great ! 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
The map / filter / reduce pattern would look like this 
Pro : the API can be optimized without touching the code 
Cons … 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
1) Suppose persons is a really BIG list 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
1) Suppose persons is a really BIG list 
2 duplications : ages & agesGT20 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
1) Suppose persons is a really BIG list 
2 duplications : ages & agesGT20 
What do we do with them ? Send them to the GC 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Putting things together 
2) Suppose we have a allMatch() reducer 
allMatch is true if all the names are shorter than 20 chars 
let’s see a possible implementation of allMatch() 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<String> names = 
Lists.map(persons, p -> p.getName()) ; 
boolean allMatch = 
Lists.allMatch(names, n -> n.length() < 20) ;
#J1LBDS 
@JosePaumard 
How could one write allMatch ? 
Here is a basic implementation of allMatch 
public static <T> boolean allMatch( 
List<? extends T> list, Filter<T> filter) { 
for (T t : list) { 
if (!filter.filter(t)) { 
return false ; 
} 
} 
return true ; 
}
#J1LBDS 
@JosePaumard 
How could one write allMatch ? 
Here is a basic implementation of allMatch 
public static <T> boolean allMatch( 
List<? extends T> list, Filter<T> filter) { 
for (T t : list) { 
if (!filter.filter(t)) { 
return false ; 
} 
} 
return true ; 
} 
No need to iterate over the whole list
#J1LBDS 
@JosePaumard 
Putting things together 
When we apply the allMatch() reducer… 
… the list names has already been evaluated ! 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<String> names = 
Lists.map(persons, p -> p.getName()) ; 
boolean allMatch = 
Lists.allMatch(names, n -> n.length() < 20) ;
#J1LBDS 
@JosePaumard 
Putting things together 
When we apply the allMatch() reducer… 
… the list names has already been evaluated ! 
We lost a big opportunity for optimization ! 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<String> names = 
Lists.map(persons, p -> p.getName()) ; 
boolean allMatch = 
Lists.allMatch(names, n -> n.length() < 20) ;
#J1LBDS 
@JosePaumard 
Putting things together 
When we apply the allMatch() reducer… 
… we should have wait to apply the filter 
A good way to do that : apply the filter step lazily ! 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<String> names = 
Lists.map(persons, p -> p.getName()) ; 
boolean allMatch = 
Lists.allMatch(names, n -> n.length() < 20) ;
#J1LBDS 
@JosePaumard 
Conclusion 
Pro : 1 
Cons : 3 (at least) 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Conclusion 
Pro : 1 
Cons : 3 (at least) 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; 
int sum = Lists.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
Conclusion 
And the same goes for this one 
// applying the map / filter / reduce pattern 
List<Person> persons = ... ; 
List<Integer> ages = persons.map( persons, p -> p.getAge()) ; 
List<Integer> agesGT20 = ages.filter(ages, a -> a > 20) ; 
int sum = agesGT20.reduce(agesGT20, Integer::sum) ;
#J1LBDS 
@JosePaumard 
What about « in place » operations ? 
Not possible for the map step, because the type of the list changes 
Could be evaluated for the filter, with concurrency issues 
Doesnt make sense for the reduction
#J1LBDS 
@JosePaumard 
Conclusion (again) 
We need a new concept to handle BIG lists efficiently
#J1LBDS 
@JosePaumard 
Conclusion (again) 
We need a new concept to handle BIG lists efficiently 
The Collection framework is not the right one…
#J1LBDS 
@JosePaumard 
Conclusion (again) 
We need a new concept to handle BIG lists efficiently 
The Collection framework is not the right one 
We need something else !
#J1LBDS 
@JosePaumard 
So what pattern to choose ?
#J1LBDS 
@JosePaumard 
Introduction 
Putting map / filter / reduce methods on Collection would have led to : 
And even if it doesnt lead to viable patterns, 
it is still a pleasant way of writing things 
// map / filter / reduce pattern on collections 
int sum = persons 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ;
#J1LBDS 
@JosePaumard 
Introduction 
Let’s keep the same kind of pattern and add a stream() 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ;
#J1LBDS 
@JosePaumard 
Introduction 
Collection.stream() returns a Stream : new interface 
New interface = our hands are free ! 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ;
#J1LBDS 
@JosePaumard 
New Collection interface 
So we need a new method on Collection 
public interface Collection<E> { 
// our good old methods 
Stream<E> stream() ; 
}
#J1LBDS 
@JosePaumard 
New Collection interface 
Problem : ArrayList doesnt compile anymore… 
Something has to be done ! 
public interface Collection<E> { 
// our good old methods 
Stream<E> stream() ; 
}
#J1LBDS 
@JosePaumard 
Interfaces 
We need to be able to add methods on interfaces… 
… without providing the implementation in the implementing classes!
#J1LBDS 
@JosePaumard 
Interfaces 
We need to be able to add methods on interfaces… 
… without providing the implementation in the implementing classes! 
Not possible in Java 7
#J1LBDS 
@JosePaumard 
Interfaces 
We need to be able to add methods on interfaces… 
… without providing the implementation in the implementing classes! 
Not possible in Java 7 
Solution: change the way interfaces work in Java
#J1LBDS 
@JosePaumard 
New interfaces
#J1LBDS 
@JosePaumard 
Java 8 interfaces 
ArrayList needs to know the implementation of stream()… 
public interface Collection<E> { 
// our good old methods 
Stream<E> stream() ; 
}
#J1LBDS 
@JosePaumard 
Java 8 interfaces 
Let’s put it in the interface ! 
public interface Collection<E> { 
// our good old methods 
default Stream<E> stream() { 
return ... ; 
} 
}
#J1LBDS 
@JosePaumard 
Java 8 interfaces 
Let’s introduce default methods in Java 
Default methods are about interface evolution 
Allows the extension of old interfaces 
public interface Collection<E> { 
// our good old methods 
default Stream<E> stream() { 
return ... ; 
} 
}
#J1LBDS 
@JosePaumard 
Interfaces vs Abstract classes 
Does an interface become the same as an abstract class ?
#J1LBDS 
@JosePaumard 
Interfaces vs Abstract classes 
Does an interface become the same as an abstract class ? 
No! 
-an abstract class can have field, ie a state 
-an abstract class has a constructor
#J1LBDS 
@JosePaumard 
Default methods 
Does it bring multiple inheritance to Java ?
#J1LBDS 
@JosePaumard 
Default methods 
Does it bring multiple inheritance to Java ? 
Yes ! But we already have it
#J1LBDS 
@JosePaumard 
Default methods 
Does it bring multiple inheritance to Java ? 
Yes ! But we already have it 
public class String 
implements Serializable, Comparable<String>, CharSequence { 
// ... 
}
#J1LBDS 
@JosePaumard 
Default methods 
What we have so far is multiple inheritance of type
#J1LBDS 
@JosePaumard 
Default methods 
What we have so far is multiple inheritance of type 
What we get in Java 8 is multiple inheritance of behavior
#J1LBDS 
@JosePaumard 
Default methods 
What we have so far is multiple inheritance of type 
What we get in Java 8 is multiple inheritance of behavior 
What we dont have is multiple inheritance of state
#J1LBDS 
@JosePaumard 
Default methods 
What we have so far is multiple inheritance of type 
What we get in Java 8 is multiple inheritance of behavior 
What we dont have is multiple inheritance of state 
… and this is where the trouble is !
#J1LBDS 
@JosePaumard 
Default methods 
Will we have conflicts ?
#J1LBDS 
@JosePaumard 
Default methods 
Will we have conflicts ? 
Yes, so we need rules to handle them
#J1LBDS 
@JosePaumard 
Default methods 
public class C implements A, B { 
// ... 
}
#J1LBDS 
@JosePaumard 
Default methods 
Example #1 
public interface A { 
default String a() { ... } 
} 
public interface B { 
default String a() { ... } 
} 
public class C implements A, B { 
// ... 
}
#J1LBDS 
@JosePaumard 
Default methods 
Example #1 
Compile time error : 
class C inherits unrelated defaults for a() from types A and B 
public interface A { 
default String a() { ... } 
} 
public interface B { 
default String a() { ... } 
} 
public class C implements A, B { 
// ... 
}
#J1LBDS 
@JosePaumard 
Default methods 
Rule #1 
Class wins ! 
No default if an implementation is present 
public interface A { 
default String a() { ... } 
} 
public interface B { 
default String a() { ... } 
} 
public class C implements A, B { 
public String a() { ... } 
}
#J1LBDS 
@JosePaumard 
Default methods 
Rule #2 
A is more specific than B : A.a() is chosen 
public interface A extends B { 
default String a() { ... } 
} 
public interface B { 
default String a() { ... } 
} 
public class C implements A, B { 
// ... 
}
#J1LBDS 
@JosePaumard 
Default methods 
Back to rule #1 
We can also make an explicit call 
public class C implements A, B { 
public String a() { return B.super(a) ; } 
} 
public interface A { 
default String a() { ... } 
} 
public interface B { 
default String a() { ... } 
}
#J1LBDS 
@JosePaumard 
2 simple rules 
To handle the conflict of multiple inheritance of behavior
#J1LBDS 
@JosePaumard 
2 simple rules 
To handle the conflict of multiple inheritance of behavior 
1)Class wins !
#J1LBDS 
@JosePaumard 
2 simple rules 
To handle the conflict of multiple inheritance of behavior 
1)Class wins ! 
2)More specific interfaces wins over less specific
#J1LBDS 
@JosePaumard 
2 simple rules 
To handle the conflict of multiple inheritance of behavior 
1)Class wins ! 
2)More specific interfaces wins over less specific
#J1LBDS 
@JosePaumard 
An example 
Everybody who writes an implementation of Iterator 
writes this : 
public class MyIterator implements Iterator<E> { 
// some critical business code 
public void remove() { 
throw new UnsupportedOperationException("Naah !!!!!!") ; 
} ; 
}
#J1LBDS 
@JosePaumard 
An example 
Thanks to Java 8 : 
No silly implementation of remove() anymore ! 
public interface Iterator<E> { default void remove() { throw new UnsupportedOperationException("remove") ; } ; }
#J1LBDS 
@JosePaumard 
So the concept of « interface » changed in Java 8 
public class HelloWorld { 
// souvenir souvenir 
public static void main(String[] args) { 
System.out.println("Hello world!") ; 
} ; 
} 
Java 8 interfaces
#J1LBDS 
@JosePaumard 
Java 8 interfaces 
So the concept of « interface » changed in Java 8 
I mean, really 
public interface HelloWorld { // souvenir souvenir public static void main(String[] args) { System.out.println("Hello world!") ; } ; }
#J1LBDS 
@JosePaumard 
Java 8 interfaces 
1)Default methods, multiple behavior inheritance 
Rules to handle conflicts, solved at compile time 
2)Static methods in interfaces 
Will bring new patterns and new ways to write APIs
#J1LBDS 
@JosePaumard 
Where are we ? 
1)We have a new syntax 
2)We have a new pattern to implement 
3)We have new interfaces to keep the backward compatibily
#J1LBDS 
@JosePaumard 
The Stream API
#J1LBDS 
@JosePaumard 
What is a Stream 
From a technical point of view : a typed interface 
« a stream of String »
#J1LBDS 
@JosePaumard 
What is a Stream 
From a technical point of view : a typed interface 
Other classes for primitive types : 
« a stream of String » 
IntStream, LongStream, DoubleStream
#J1LBDS 
@JosePaumard 
It’s a new notion 
It looks like a collection, but… 
-It is built on a « source », that can be a collection 
-No data needs to be provided at build time 
-No limit on what the source can produce
#J1LBDS 
@JosePaumard 
It’s a new notion 
A stream can be built on : 
-A collection or an array 
-An iterator 
-An I/O source 
Some of those can be « infinite »
#J1LBDS 
@JosePaumard 
It’s a new notion 
1)A stream doesnt hold any data 
It’s just an object on which one can declare operations 
Streams are about « specifying computations »
#J1LBDS 
@JosePaumard 
It’s a new notion 
1)A stream doesnt hold any data 
2)A stream cant modify its source 
Consequence : it can use parallel processing
#J1LBDS 
@JosePaumard 
It’s a new notion 
1)A stream doesnt hold any data 
2)A stream cant modify its source 
3)A source can be infinite 
So we need a way to guarantee that computations will be conducted in finite time
#J1LBDS 
@JosePaumard 
It’s a new notion 
1)A stream doesnt hold any data 
2)A stream cant modify its source 
3)A source can be infinite 
4)A stream works lazily 
Then optimizations can be made among the different operations 
We need a way / convention to trigger the computations
#J1LBDS 
@JosePaumard 
How can we build a stream ? 
Many ways… 
1)From a collection : method Collection.stream 
Collection<String> collection = ... ; 
Stream<String> stream = collection.stream() ;
#J1LBDS 
@JosePaumard 
How can we build a stream ? 
Many ways… 
1)From a collection : method Collection.stream 
2)From an array : Arrays.stream(Object []) 
Stream<String> stream2 = 
Arrays.stream(new String [] {"one", "two", "three"}) ;
#J1LBDS 
@JosePaumard 
How can we build a stream ? 
Many ways… 
1)From a collection : method Collection.stream 
2)From an array : Arrays.stream(Object []) 
3)From factory methods in Stream, IntStream, … 
Stream<String> stream1 = Stream.of("one", "two", "three") ;
#J1LBDS 
@JosePaumard 
How can we build a stream ? 
Some last patterns 
Stream.empty() ; // returns an empty Stream 
Stream.of(T t) ; // a stream with a single element 
Stream.generate(Supplier<T> s) ; 
Stream.iterate(T seed, UnaryOperator<T> f) ;
#J1LBDS 
@JosePaumard 
How can we build a stream ? 
Other ways scattered in the JDK 
string.chars() ; // returns a IntStream 
lineNumberReader.lines() ; // returns a Stream<String> 
random.ints() ; // return a IntStream
#J1LBDS 
@JosePaumard 
Back to our map / filter / reduce example 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ; 
A 1st example 
Builds a stream on a List
#J1LBDS 
@JosePaumard 
A 1st example 
Back to our map / filter / reduce example 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ; 
Declares operations
#J1LBDS 
@JosePaumard 
A 1st example 
Back to our map / filter / reduce example 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ; 
Triggers the computation
#J1LBDS 
@JosePaumard 
A 1st example 
Back to our map / filter / reduce example 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ; 
Default value, in case the stream is empty
#J1LBDS 
@JosePaumard 
3 things on Streams
#J1LBDS 
@JosePaumard 
1) Two types of operations 
One can declare operations on a Stream 
Two types of operations : 
1)Intermediate operations : declarations, processed lazily 
ex : map, filter
#J1LBDS 
@JosePaumard 
1) Two types of operations 
One can declare operations on a Stream 
Two types of operations : 
1)Intermediate operations : declarations, processed lazily 
ex : map, filter 
2)Terminal operations : trigger the computations 
ex : reduce
#J1LBDS 
@JosePaumard 
2) State of a stream 
The implementation of Stream has a state : 
-SIZED : the number of elements is known 
-ORDERED : the order matters (List) 
-DISTINCT : all elements are unique (Set) 
-SORTED : all elements have been sorted (SortedSet)
#J1LBDS 
@JosePaumard 
2) State of a stream 
Some operations change that : 
-filtering removes the SIZED 
-mapping removes DISTINCT and SORTED
#J1LBDS 
@JosePaumard 
2) State of a stream 
It’s all about optimization! 
Collection<Person> collection = ... ; 
Stream<Person> stream = collection.stream() ; 
stream.distinct() 
.map(Person::getAge) 
.filter(a -> a > 20) 
.reduce(0, Integer::sum) ;
#J1LBDS 
@JosePaumard 
2) State of a stream 
It’s all about optimization! 
Collection<Person> collection = new HashSet<>() ; Stream<Person> stream = collection.stream() ; // DISTINCT stream.distinct() // DISTINCT = will not do anything .map(Person::getAge) .filter(a -> a > 20) .reduce(0, Integer::sum) ;
#J1LBDS 
@JosePaumard 
2) State of a stream 
It’s all about optimization! 
Collection<Person> collection = ... ; 
Stream<Person> stream = collection.stream() ; 
stream.sorted() 
.forEach(System.out::println) ;
#J1LBDS 
@JosePaumard 
2) State of a stream 
It’s all about optimization! 
Collection<Person> collection = new SortedSet<>() ; Stream<Person> stream = collection.stream() ; // SORTED stream.sorted() // SORTED = doesnt do anything .forEach(System.out::println) ;
#J1LBDS 
@JosePaumard 
3) Stateless / stateful operations 
Stateless / stateful operations 
Some operations are stateless : 
It means that they dont need more information than the one held by their parameters 
persons.stream().map(p -> p.getAge()) ;
#J1LBDS 
@JosePaumard 
3) Stateless / stateful operations 
Stateless / stateful operations 
Some operations are stateless : 
Some needs to retain information : 
persons.stream().map(p -> p.getAge()) ; 
stream.limit(10_000_000) ; // select the 10M first elements
#J1LBDS 
@JosePaumard 
Example 
Let’s sort an array of String 
Random rand = new Random() ; String [] strings = new String[10_000_000] ; for (int i = 0 ; i < strings.length ; i++) { strings[i] = Long.toHexString(rand.nextLong()) ; }
#J1LBDS 
@JosePaumard 
Example 
Let’s sort an array of String 
Soooo Java 7… 
Random rand = new Random() ; 
String [] strings = new String[10_000_000] ; 
for (int i = 0 ; i < strings.length ; i++) { 
strings[i] = Long.toHexString(rand.nextLong()) ; 
}
#J1LBDS 
@JosePaumard 
Example 
Let’s sort an array of String 
Better ? 
Random rand = new Random() ; Stream<String> stream = Stream.generate( () -> Long.toHexString(rand.nextLong()) ) ;
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Better ! 
// Random rand = new Random() ; 
Stream<String> stream = 
Stream.generate( 
() -> 
Long.toHexString(ThreadLocalRandom.current().nextLong()) 
) ; 
Example
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Example 
// other way Stream<String> stream = ThreadLocalRandom .current() .longs() // returns a LongStream .mapToObj(l -> Long.toHexString(l)) ;
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Example 
// other way 
Stream<String> stream = 
ThreadLocalRandom 
.current() 
.longs() 
.mapToObj(Long::toHexString) ;
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Example 
// other way Stream<String> stream = ThreadLocalRandom .current() .longs() .mapToObj(Long::toHexString) .limit(10_000_000) .sorted() ; 
T = 4 ms
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Example 
// other way 
Stream<String> stream = 
ThreadLocalRandom 
.current() 
.longs() 
.mapToObj(Long::toHexString) 
.limit(10_000_000) 
.sorted() ; 
Object [] sorted = stream.toArray() ;
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Example 
// other way 
Stream<String> stream = 
ThreadLocalRandom 
.current() 
.longs() 
.mapToObj(Long::toHexString) 
.limit(10_000_000) 
.sorted() ; 
Object [] sorted = stream.toArray() ; 
T = 14 s
#J1LBDS 
@JosePaumard 
Let’s sort an array of String 
Example 
// other way 
Stream<String> stream = 
ThreadLocalRandom 
.current() 
.longs() 
.mapToObj(Long::toHexString) 
.limit(10_000_000) 
.sorted() ; 
Object [] sorted = stream.toArray() ; 
T = 14 s 
Intermediate calls !
#J1LBDS 
@JosePaumard 
More on stream operations 
1)There are intermediate and terminal operations 
2)A stream is processed on a terminal operation call
#J1LBDS 
@JosePaumard 
More on stream operations 
1)There are intermediate and terminal operations 
2)A stream is processed on a terminal operation call 
3)Only one terminal operation is allowed 
4)It cannot be processed again 
If needed another stream should be built on the source
#J1LBDS 
@JosePaumard 
Parallel Streams
#J1LBDS 
@JosePaumard 
Optimization 
The first optimization (well, laziness was first !) we need is parallelism 
The fork / join enable parallel programming since JDK 7 
But writing tasks is hard and does not always lead to better performances
#J1LBDS 
@JosePaumard 
Optimization 
The first optimization (well, laziness was first !) we need is parallelism 
The fork / join enable parallel programming since JDK 7 
But writing tasks is hard and does not always lead to better performances 
Using the parallel stream API is much more secure
#J1LBDS 
@JosePaumard 
How to build a parallel stream ? 
Two patterns 
1)Call parallelStream() instead of stream() 
2)Call parallel() on an existing stream 
Stream<String> s = strings.parallelStream() ; 
Stream<String> s = strings.stream().parallel() ;
#J1LBDS 
@JosePaumard 
Can we decide the # of cores ? 
Answer is yes, but it’s tricky 
System.setProperty( 
"java.util.concurrent.ForkJoinPool.common.parallelism", 2) ;
#J1LBDS 
@JosePaumard 
Can we decide the # of cores ? 
Answer is yes, but it’s tricky 
List<Person> persons = ... ; 
ForkJoinPool fjp = new ForkJoinPool(2) ; 
fjp.submit( 
() -> // 
persons.stream().parallel() // 
.mapToInt(p -> p.getAge()) // Callable<Integer> 
.filter(age -> age > 20) // 
.average() // 
).get() ;
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
Example : performances 
Code 1 
List<Long> list = new ArrayList<>(10_000_100) ; 
for (int i = 0 ; i < 10_000_000 ; i++) { 
list.add(ThreadLocalRandom.current().nextLong()) ; 
}
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
Example : performances 
Code 2 
Stream<Long> stream = 
Stream.generate(() -> ThreadLocalRandom.current().nextLong()) ; 
List<Long> list = stream.limit(10_000_000).collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
Example : performances 
Code 3 
Stream<Long> stream = 
ThreadLocalRandom.current().longs(10_000_000).mapToObj(Long::new) ; 
List<Long> list = stream.collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
Example : performances 
Serial 
Parallel 
Code 1 (for) 
270 ms 
Code 2 (limit) 
310 ms 
Code 3 (longs) 
250 ms
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
Example : performances 
Serial 
Parallel 
Code 1 (for) 
270 ms 
Code 2 (limit) 
310 ms 
500 ms 
Code 3 (longs) 
250 ms 
320 ms
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
A sneaky problem 
List<Person> persons = new ArrayList<>() ; // some code to add people persons.stream() .map(Person::getAge) .collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
A sneaky problem 
List<Person> persons = new ArrayList<>() ; 
// some code to add people 
persons.stream() // ORDERED ! 
.map(Person::getAge) 
.collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
A sneaky problem 
List<Person> persons = new ArrayList<>() ; // some code to add people persons.stream() .parallel() .map(Person::getAge) .collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Is parallelism really that simple ? 
A sneaky problem 
List<Person> persons = new ArrayList<>() ; 
// some code to add people 
persons.stream() 
.unordered() 
.parallel() 
.map(Person::getAge) 
.collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Parallelism 
Parallelism implies overhead most of the time 
Badly configured parallel operations can lead to unneeded computations that will slow down the overall process 
Unnecessary ordering of a stream will lead to performance hits
#J1LBDS 
@JosePaumard 
Reductions
#J1LBDS 
@JosePaumard 
A simple reduction 
Sum of ages 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.reduce(0, (a1, a2) -> a1 + a2) ;
#J1LBDS 
@JosePaumard 
It would be nice to be able to write : 
But there’s no sum() on Stream<T> 
What would be the sense of « adding persons » ? 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.sum() ; 
A simple reduction
#J1LBDS 
@JosePaumard 
A simple reduction 
It would be nice to be able to write : 
But there’s no sum() on Stream<T> 
There’s one on IntStream ! 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.map(p -> p.getAge()) 
.filter(a -> a > 20) 
.sum() ;
#J1LBDS 
@JosePaumard 
A simple reduction 
2nd version : 
Value if persons is an empty list : 0 
// map / filter / reduce pattern on collections int sum = persons.stream() .map(Person::getAge) .filter(a -> a > 20) .mapToInt(Integer::intValue) .sum() ;
#J1LBDS 
@JosePaumard 
A simple reduction 
2nd version : 
Value if persons is an empty list : 0 
// map / filter / reduce pattern on collections 
int sum = persons.stream() 
.mapToInt(Person::getAge) 
.filter(a -> a > 20) 
// .mapToInt(Integer::intValue) 
.sum() ;
#J1LBDS 
@JosePaumard 
Default values
#J1LBDS 
@JosePaumard 
A simple reduction 
What about max() and min() ? 
How can one chose a default value ? 
// map / filter / reduce pattern on collections 
....... = persons.stream() 
.mapToInt(Person::getAge) 
.filter(a -> a > 20) 
.max() ;
#J1LBDS 
@JosePaumard 
Problem with the default value 
The « default value » is a tricky notion
#J1LBDS 
@JosePaumard 
Problem with the default value 
The « default value » is a tricky notion 
1)The « default value » is the reduction of the empty set
#J1LBDS 
@JosePaumard 
Problem with the default value 
The « default value » is a tricky notion 
1)The « default value » is the reduction of the empty set 
2)But it’s also the identity element for the reduction
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard 
Problem with the default value 
The « default value » is a tricky notion 
1)The « default value » is the reduction of the empty set 
2)But it’s also the identity element for the reduction
#J1LBDS 
@JosePaumard 
Problem with the default value 
Problem : max() and min() have no identity element 
eg : an element e for which max(e, a) = a
#J1LBDS 
@JosePaumard 
Problem with the default value 
Problem : max() and min() have no identity element 
eg : an element e for which max(e, a) = a 
0 cant be, max(0, -1) is not -1…
#J1LBDS 
@JosePaumard 
Problem with the default value 
Problem : max() and min() have no identity element 
eg : an element e for which max(e, a) = a 
0 cant be, max(0, -1) is not -1… 
−∞ is not an integer
#J1LBDS 
@JosePaumard 
Problem with the default value 
Problem : max() and min() have no identity element 
eg : an element e for which max(e, a) = a 
0 cant be, max(0, -1) is not -1… 
−∞ is not an integer 
Integer.MIN_VALUE
#J1LBDS 
@JosePaumard 
Problem with the default value 
So what is the default value of max() and min() ?
#J1LBDS 
@JosePaumard 
Problem with the default value 
So what is the default value of max() and min() ? 
Answer : there is no default value for max() and min()
#J1LBDS 
@JosePaumard 
Problem with the default value 
So what is the returned type of the max() method ? 
// map / filter / reduce pattern on collections 
....... = persons.stream() 
.mapToInt(Person::getAge) 
.filter(a -> a > 20) 
.max() ;
#J1LBDS 
@JosePaumard 
Problem with the default value 
So what is the returned type of the max() method ? 
If it’s int, then the default value will be 0… 
// map / filter / reduce pattern on collections 
....... = persons.stream() 
.mapToInt(Person::getAge) 
.filter(a -> a > 20) 
.max() ;
#J1LBDS 
@JosePaumard 
Problem with the default value 
So what is the returned type of the max() method ? 
If it’s Integer, then the default value will be null… 
// map / filter / reduce pattern on collections 
....... = persons.stream() 
.mapToInt(Person::getAge) 
.filter(a -> a > 20) 
.max() ;
#J1LBDS 
@JosePaumard 
Optionals 
Since there’s none, we need another notion 
« there might be no result » 
// map / filter / reduce pattern on collections 
OptionalInt optionalMax = persons.stream() 
.mapToInt(Person::getAge) 
.filter(a -> a > 20) 
.max() ;
#J1LBDS 
@JosePaumard 
Optionals 
What can I do with OptionalInt ? 
1st pattern : test if it holds a value 
OptionalInt optionalMax = ... ; 
int max ; 
if (optionalMax.isPresent()) { 
max = optionalMax.get() ; 
} else { 
max = ... ; // decide a « default value » 
}
#J1LBDS 
@JosePaumard 
Optionals 
What can I do with OptionalInt ? 
2nd pattern : read the held value, can get an exception 
OptionalInt optionalMax = ... ; 
// throws NoSuchElementException if no held value 
int max = optionalMax.getAsInt() ;
#J1LBDS 
@JosePaumard 
Optionals 
What can I do with OptionalInt ? 
3rd pattern : read the held value, giving a default value 
OptionalInt optionalMax = ... ; 
// get 0 if no held value 
int max = optionalMax.orElse(0) ;
#J1LBDS 
@JosePaumard 
Optionals 
What can I do with OptionalInt ? 
4th pattern : read the held value, or throw an exception 
OptionalInt optionalMax = ... ; 
// exceptionSupplier will supply an exception, if no held value 
int max = optionalMax.orElseThrow(exceptionSupplier) ;
#J1LBDS 
@JosePaumard 
Available optionals 
Optional<T> 
OptionalInt, OptionalLong, OptionalDouble
#J1LBDS 
@JosePaumard 
Available reductions 
On Stream<T> : 
-reduce(), with different parameters 
-count(), min(), max() 
-anyMatch(), allMatch(), noneMatch() 
-findFirst(), findAny() 
-toArray() 
-forEach(), forEachOrdered()
#J1LBDS 
@JosePaumard 
Available reductions 
On IntStream, LongStream, DoubleStream : 
-average() 
-summaryStatistics()
#J1LBDS 
@JosePaumard 
Available reductions 
SummaryStatistics is an object that holds : 
-Count, Min, Max, Sum, Average 
It’s a consumer, so it can be easily extended to compute other statistics
#J1LBDS 
@JosePaumard 
Mutable reductions
#J1LBDS 
@JosePaumard 
Mutable reductions : example 1 
Use of the helper class : Collectors 
List<String> strings = stream .map(Object::toString) .collect(Collectors.toList()) ;
#J1LBDS 
@JosePaumard 
Mutable reductions : example 2 
Concatenating strings with a helper 
String names = persons 
.stream() 
.map(Person::getName) 
.collect(Collectors.joining()) ;
#J1LBDS 
@JosePaumard 
Mutable reductions 
Common things : 
-have a container : Collection or StringBuilder 
-have a way to add an element to the container 
-have a way to merge two containers (for parallelization)
#J1LBDS 
@JosePaumard 
Mutable reductions : example 1 
Putting things together : 
ArrayList<String> strings = 
stream 
.map(Object::toString) 
.collect( 
() -> new ArrayList<String>(), // the supplier 
(suppList, s) -> suppList.add(s), // the accumulator 
(suppL1, suppL2) -> suppL1.addAll(suppL2) // the combiner 
) ;
#J1LBDS 
@JosePaumard 
Mutable reductions : example 1 
Putting things together : 
ArrayList<String> strings = stream .map(Object::toString) .collect( ArrayList::new, // the supplier ArrayList::add, // the accumulator ArrayList::addAll // the combiner ) ;
#J1LBDS 
@JosePaumard 
Mutable reductions : example 1 
Putting things together : 
ArrayList<String> strings = 
stream 
.map(Object::toString) 
.collect( 
Collectors.toList() 
) ;
#J1LBDS 
@JosePaumard 
Collectors
#J1LBDS 
@JosePaumard 
The Collectors class 
A rich toolbox (37 methods) for various types of reductions 
-counting, minBy, maxBy 
-summing, averaging, summarizing 
-joining 
-toList, toSet 
And 
- mapping, groupingBy, partionningBy
#J1LBDS 
@JosePaumard 
The Collectors class 
Average, Sum, Count 
persons 
.stream() 
.collect(Collectors.averagingDouble(Person::getAge)) ; 
persons 
.stream() 
.collect(Collectors.counting()) ;
#J1LBDS 
@JosePaumard 
The Collectors class 
Concatenating the names in a String 
String names = persons .stream() .map(Person::getName) .collect(Collectors.joining(", ")) ;
#J1LBDS 
@JosePaumard 
The Collectors class 
Accumulating in a List, Set 
Set<Person> setOfPersons = persons 
.stream() 
.collect( 
Collectors.toSet()) ;
#J1LBDS 
@JosePaumard 
The Collectors class 
Accumulating in a custom collection 
TreeSet<Person> treeSetOfPersons = persons .stream() .collect( Collectors.toCollection(TreeSet::new)) ;
#J1LBDS 
@JosePaumard 
The Collectors class 
Getting the max according to a comparator 
Bonus : new API to build comparators 
Optional<Person> optionalPerson = persons 
.stream() 
.collect( 
Collectors.maxBy( 
Comparator.comparing(Person::getAge)) ;
#J1LBDS 
@JosePaumard 
Building comparators 
New API to build comparators in a declarative way 
Comparator<Person> comp = Comparator.comparing(Person::getLastName) .thenComparing(Person::getFirstName) .thenComparing(Person::getAge) ;
#J1LBDS 
@JosePaumard 
Building comparators 
New API to build comparators in a declarative way 
Comparator<Person> comp = 
Comparator.comparing(Person::getLastName) 
.thenComparing(Person::getFirstName) 
.thenComparing(Person::getAge) ; 
Comparator<Person> comp = 
Comparator.comparing(Person::getLastName) 
.reversed() ;
#J1LBDS 
@JosePaumard 
Building comparators 
New API to build comparators in a declarative way 
Comparator<Person> comp = 
Comparator.comparing(Person::getLastName) 
.thenComparing(Person::getFirstName) 
.thenComparing(Person::getAge) ; 
Comparator<Person> comp = 
Comparator.nullsFirst( 
Comparator.comparing(Person::getLastName) 
) ;
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
« Grouping by » builds hash maps 
-must explain how the keys are built 
-by default the values are put in a list 
-may specify a downstream (ie a collector)
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
Grouping a list of persons by their age 
Map<Integer, List<Person>> map = 
persons 
.stream() 
.collect( 
Collectors.groupingBy(Person::getAge)) ;
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
Grouping a list of persons by their age 
Map<Integer, Set<Person>> map = persons .stream() .collect( Collectors.groupingBy( Person::getAge, Collectors.toSet() // the downstream ) ;
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
Grouping a list of persons names by their age 
Map<Integer, Set<String>> map = 
persons 
.stream() 
.collect( 
Collectors.groupingBy( 
Person::getAge, 
Collectors.mapping( // 
Person::getLastName, // the downstream 
Collectors.toSet() // 
) 
) ;
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
Grouping a list of persons names by their age 
Map<Integer, TreeSet<String>> map = persons .stream() .collect( Collectors.groupingBy( Person::getAge, Collectors.mapping( Person::getLastName, Collectors.toCollection(TreeSet::new) ) ) ;
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
Grouping a list of blah blah blah 
TreeMap<Integer, TreeSet<String>> map = 
persons 
.stream() 
.collect( 
Collectors.groupingBy( 
Person::getAge, 
TreeMap::new, 
Collectors.mapping( 
Person::getLastName, 
Collectors.toCollection(TreeSet::new) 
) 
) ;
#J1LBDS 
@JosePaumard 
The Collector API : groupingBy 
Example : creating an age histogram 
Gives the # of persons by age 
Map<Integer, Long> map = persons .stream() .collect( Collectors.groupingBy(Person::getAge, Collectors.counting()) ) ;
#J1LBDS 
@JosePaumard 
The Collector API : partioningBy 
Creates a Map<Boolean, …> on a predicate 
-the map has 2 keys : TRUE and FALSE 
-may specify a downstream
#J1LBDS 
@JosePaumard 
The Collector API : partioningBy 
Creates a Map<Boolean, …> on a predicate 
map.get(TRUE) returns the list people older than 20 
Map<Boolean, List<Person>> map = 
persons 
.stream() 
.collect( 
Collectors.partitioningBy(p -> p.getAge() > 20) 
) ;
#J1LBDS 
@JosePaumard 
The Collector API : partioningBy 
Can further process the list of persons 
Map<Boolean, TreeSet<String>> map = persons .stream() .collect( Collectors.partitioningBy( p -> p.getAge() > 20, Collectors.mapping( Person::getLastName, Collectors.toCollection(TreeSet::new)) ) ) ) ;
#J1LBDS 
@JosePaumard 
The Collector API : collectingAndThen 
Collect data with a downstream 
Then apply a function called a « finisher » 
Useful for putting the result in a immutable collection
#J1LBDS 
@JosePaumard 
The Collector API : collectingAndThen 
In this case « Map::entrySet » is a finisher 
Set<Map.Entry<Integer, List<Person>>> set = 
persons 
.stream() 
.collect( 
Collectors.collectingAndThen( 
Collectors.groupingBy( 
Person::getAge), // downstream, builds a map 
Map::entrySet // finisher, applied on the map 
) ;
#J1LBDS 
@JosePaumard 
The Collector API : collectingAndThen 
Map<Integer, List<Person>> map = // immutable 
persons 
.stream() 
.collect( 
Collectors.collectingAndThen( 
Collectors.groupingBy( 
Person::getAge), // the downstream builds a map 
Collections::unmodifiableMap // finisher is applied to the 
// map 
) ;
#J1LBDS 
@JosePaumard 
Some real examples 
https://github.com/JosePaumard/jdk8-lambda-tour
#J1LBDS 
@JosePaumard 
Conclusion
#J1LBDS 
@JosePaumard 
Conclusion 
Why are lambdas introduced in Java 8 ?
#J1LBDS 
@JosePaumard 
Conclusion 
Why are lambdas introduced in Java 8 ? 
Because it’s in the mood !
#J1LBDS 
@JosePaumard
#J1LBDS 
@JosePaumard 
Conclusion 
Why are lambdas introduced in Java 8 ? 
Because it’s in the mood !
#J1LBDS 
@JosePaumard 
Conclusion 
Why are lambdas introduced in Java 8 ? 
Because it’s in the mood ! 
Because it allows to write more compact code !
#J1LBDS 
@JosePaumard 
Compact code is better ! 
An example of compact code (in C) 
http://www.codeproject.com/Articles/2228/Obfuscating-your-Mandelbrot-code 
#include "stdio.h" 
main() { 
int b=0,c=0,q=60,_=q;for(float i=-20,o,O=0,l=0,j,p;j=O*O,p=l*l, 
(!_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,p=j=O=l=0,c++,stdout)), 
_=q:l=2*O*l+i/20,O=j-p+o),b=c%q,c<2400;o=-2+b*.05) ; 
}
#J1LBDS 
@JosePaumard 
Compact code is better ! 
An example of compact code (in C) 
http://www.codeproject.com/Articles/2228/Obfuscating-your-Mandelbrot-code 
#include "stdio.h" 
main() { 
int b=0,c=0,q=60,_=q;for(float i=-20,o,O=0,l=0,j,p;j=O*O,p=l*l, 
(!_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,p=j=O=l=0,c++,stdout)), 
_=q:l=2*O*l+i/20,O=j-p+o),b=c%q,c<2400;o=-2+b*.05) ; 
} 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++++++++++++++++++++++++++++++++++ ++ +++++++++++ 
+++++++++++++++++++++++++++++++++++ +++++++ 
++++++++++++++++++++++++++++++++++++ +++++++ 
+++++++++++++++++++++++++++++++++++ ++++++++ 
++++++++++++++++++++++++++++++++++ +++++++ 
+++++++++++++++++++++++++++++++++ +++++ 
+++++++++++++++++++++++++++++++++ ++++++ 
+++++++++++++++++++++++ + +++++ ++++++ 
+++++++++++++++++++++++ ++ ++++++ 
++++++++++++++++++++++ + ++++++ 
++++++++++++++++++++++ + ++++++ 
++++++++++++++++++++ + + +++++++ 
++++++ ++++++++ 
++++++++++++++++++++ + + +++++++ 
++++++++++++++++++++++ + ++++++ 
++++++++++++++++++++++ + ++++++ 
+++++++++++++++++++++++ ++ ++++++ 
+++++++++++++++++++++++ + +++++ ++++++ 
+++++++++++++++++++++++++++++++++ ++++++ 
+++++++++++++++++++++++++++++++++ +++++ 
++++++++++++++++++++++++++++++++++ +++++++ 
+++++++++++++++++++++++++++++++++++ ++++++++ 
++++++++++++++++++++++++++++++++++++ +++++++ 
+++++++++++++++++++++++++++++++++++ +++++++ 
++++++++++++++++++++++++++++++++++++ ++ +++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#J1LBDS 
@JosePaumard 
Conclusion 
Why are lambdas introduced in Java 8 ? 
Because it’s in the mood ! 
Because it allows to write more compact code !
#J1LBDS 
@JosePaumard 
Conclusion 
Why are lambdas introduced in Java 8 ? 
Because it brings new and efficient patterns, 
that enable easy and safe parallelization, 
-needed by modern applications 
-needed by API writers
#J1LBDS 
@JosePaumard 
Conclusion 
Java 8 is here, it’s the biggest update in 15 years
#J1LBDS 
@JosePaumard 
Conclusion 
Java 8 is here, it’s the biggest update in 15 years 
Moving to Java 8 means a lot of work for us developers ! 
-Self training 
-Changing our habits
#J1LBDS 
@JosePaumard 
Conclusion 
Java 8 is here, it’s the biggest update in 15 years 
Moving to Java 8 means a lot of work for us developers ! 
-Self training 
-Changing our habits 
-Convincing our bosses (sigh…)
#J1LBDS 
@JosePaumard 
Conclusion 
Books are there ! 
available 
available 
available 
available 
available
#J1LBDS 
@JosePaumard 
Conclusion 
Java 8 is the biggest update in 15 years 
« Java is a blue collar language. It’s not PhD thesis material but a language for a job » – James Gosling, 1997
#J1LBDS 
@JosePaumard 
Conclusion 
Java 8 is the biggest update in 15 years 
« Language features are not a goal unto themselves; language features are enablers, encouraging or discouraging certain styles and idioms » – Brian Goetz, 2013
#J1LBDS 
@JosePaumard 
Conclusion 
Java 8 is the biggest update in 15 years 
The good news is : Java is still Java !
@JosePaumard 
#J1LBDS
@JosePaumard 
#J1LBDS

More Related Content

What's hot

The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1José Paumard
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureJosé Paumard
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developersJosé Paumard
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full storyJosé Paumard
 
JFokus 50 new things with java 8
JFokus 50 new things with java 8JFokus 50 new things with java 8
JFokus 50 new things with java 8José Paumard
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developersJosé Paumard
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday lifeAndrea Iacono
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreXavier Coulon
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme SwiftMovel
 
AST Transformations
AST TransformationsAST Transformations
AST TransformationsHamletDRC
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersBartosz Kosarzycki
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performanceintelliyole
 

What's hot (20)

Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Java 8 Stream API (Valdas Zigas)
Java 8 Stream API (Valdas Zigas)Java 8 Stream API (Valdas Zigas)
Java 8 Stream API (Valdas Zigas)
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full story
 
JFokus 50 new things with java 8
JFokus 50 new things with java 8JFokus 50 new things with java 8
JFokus 50 new things with java 8
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a Datastore
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 

Viewers also liked

50 new things you can do with java 8
50 new things you can do with java 850 new things you can do with java 8
50 new things you can do with java 8José Paumard
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJosé Paumard
 
50 nouvelles choses que l'on peut faire avec Java 8
50 nouvelles choses que l'on peut faire avec Java 850 nouvelles choses que l'on peut faire avec Java 8
50 nouvelles choses que l'on peut faire avec Java 8José Paumard
 
JDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne TourJDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne TourJosé Paumard
 
API Asynchrones en Java 8
API Asynchrones en Java 8API Asynchrones en Java 8
API Asynchrones en Java 8José Paumard
 
Les Streams sont parmi nous
Les Streams sont parmi nousLes Streams sont parmi nous
Les Streams sont parmi nousJosé Paumard
 

Viewers also liked (6)

50 new things you can do with java 8
50 new things you can do with java 850 new things you can do with java 8
50 new things you can do with java 8
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
 
50 nouvelles choses que l'on peut faire avec Java 8
50 nouvelles choses que l'on peut faire avec Java 850 nouvelles choses que l'on peut faire avec Java 8
50 nouvelles choses que l'on peut faire avec Java 8
 
JDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne TourJDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne Tour
 
API Asynchrones en Java 8
API Asynchrones en Java 8API Asynchrones en Java 8
API Asynchrones en Java 8
 
Les Streams sont parmi nous
Les Streams sont parmi nousLes Streams sont parmi nous
Les Streams sont parmi nous
 

Similar to Autumn collection JavaOne 2014

Autumn collections : from iterable to lambdas, streams and collectors
Autumn collections : from iterable to lambdas, streams and collectorsAutumn collections : from iterable to lambdas, streams and collectors
Autumn collections : from iterable to lambdas, streams and collectorsJosé Paumard
 
R getting spatial
R getting spatialR getting spatial
R getting spatialFAO
 
10. Getting Spatial
10. Getting Spatial10. Getting Spatial
10. Getting SpatialFAO
 
R Spatial Analysis using SP
R Spatial Analysis using SPR Spatial Analysis using SP
R Spatial Analysis using SPtjagger
 
Cutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optionalCutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optionalGraham Charters
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
Data preparation, depth function
Data preparation, depth functionData preparation, depth function
Data preparation, depth functionFAO
 
ACADILD:: HADOOP LESSON
ACADILD:: HADOOP LESSON ACADILD:: HADOOP LESSON
ACADILD:: HADOOP LESSON Padma shree. T
 
Taking Inspiration From The Functional World
Taking Inspiration From The Functional WorldTaking Inspiration From The Functional World
Taking Inspiration From The Functional WorldPiotr Solnica
 
Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4MongoDB
 
DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009Dirkjan Bussink
 

Similar to Autumn collection JavaOne 2014 (14)

Autumn collections : from iterable to lambdas, streams and collectors
Autumn collections : from iterable to lambdas, streams and collectorsAutumn collections : from iterable to lambdas, streams and collectors
Autumn collections : from iterable to lambdas, streams and collectors
 
Java 8 revealed
Java 8 revealedJava 8 revealed
Java 8 revealed
 
10. R getting spatial
10.  R getting spatial10.  R getting spatial
10. R getting spatial
 
R getting spatial
R getting spatialR getting spatial
R getting spatial
 
10. Getting Spatial
10. Getting Spatial10. Getting Spatial
10. Getting Spatial
 
R Spatial Analysis using SP
R Spatial Analysis using SPR Spatial Analysis using SP
R Spatial Analysis using SP
 
Cutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optionalCutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optional
 
Java 8 by example!
Java 8 by example!Java 8 by example!
Java 8 by example!
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Data preparation, depth function
Data preparation, depth functionData preparation, depth function
Data preparation, depth function
 
ACADILD:: HADOOP LESSON
ACADILD:: HADOOP LESSON ACADILD:: HADOOP LESSON
ACADILD:: HADOOP LESSON
 
Taking Inspiration From The Functional World
Taking Inspiration From The Functional WorldTaking Inspiration From The Functional World
Taking Inspiration From The Functional World
 
Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4
 
DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009
 

More from José Paumard

Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19José Paumard
 
From Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfFrom Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfJosé Paumard
 
The Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingThe Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingJosé Paumard
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKJosé Paumard
 
Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsJosé Paumard
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternJosé Paumard
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapesJosé Paumard
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!José Paumard
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowJosé Paumard
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJosé Paumard
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJosé Paumard
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses étatsJosé Paumard
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauJosé Paumard
 

More from José Paumard (15)

Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19
 
From Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfFrom Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdf
 
The Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingThe Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern Matching
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patterns
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor Pattern
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn Flow
 
Java Full Throttle
Java Full ThrottleJava Full Throttle
Java Full Throttle
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
Streams in the wild
Streams in the wildStreams in the wild
Streams in the wild
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateau
 

Recently uploaded

CELL CYCLE Division Science 8 quarter IV.pptx
CELL CYCLE Division Science 8 quarter IV.pptxCELL CYCLE Division Science 8 quarter IV.pptx
CELL CYCLE Division Science 8 quarter IV.pptxJiesonDelaCerna
 
Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Jisc
 
Final demo Grade 9 for demo Plan dessert.pptx
Final demo Grade 9 for demo Plan dessert.pptxFinal demo Grade 9 for demo Plan dessert.pptx
Final demo Grade 9 for demo Plan dessert.pptxAvyJaneVismanos
 
Like-prefer-love -hate+verb+ing & silent letters & citizenship text.pdf
Like-prefer-love -hate+verb+ing & silent letters & citizenship text.pdfLike-prefer-love -hate+verb+ing & silent letters & citizenship text.pdf
Like-prefer-love -hate+verb+ing & silent letters & citizenship text.pdfMr Bounab Samir
 
MARGINALIZATION (Different learners in Marginalized Group
MARGINALIZATION (Different learners in Marginalized GroupMARGINALIZATION (Different learners in Marginalized Group
MARGINALIZATION (Different learners in Marginalized GroupJonathanParaisoCruz
 
Presiding Officer Training module 2024 lok sabha elections
Presiding Officer Training module 2024 lok sabha electionsPresiding Officer Training module 2024 lok sabha elections
Presiding Officer Training module 2024 lok sabha electionsanshu789521
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPCeline George
 
AmericanHighSchoolsprezentacijaoskolama.
AmericanHighSchoolsprezentacijaoskolama.AmericanHighSchoolsprezentacijaoskolama.
AmericanHighSchoolsprezentacijaoskolama.arsicmarija21
 
Alper Gobel In Media Res Media Component
Alper Gobel In Media Res Media ComponentAlper Gobel In Media Res Media Component
Alper Gobel In Media Res Media ComponentInMediaRes1
 
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdfEnzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdfSumit Tiwari
 
Organic Name Reactions for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions  for the students and aspirants of Chemistry12th.pptxOrganic Name Reactions  for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions for the students and aspirants of Chemistry12th.pptxVS Mahajan Coaching Centre
 
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...JhezDiaz1
 
MICROBIOLOGY biochemical test detailed.pptx
MICROBIOLOGY biochemical test detailed.pptxMICROBIOLOGY biochemical test detailed.pptx
MICROBIOLOGY biochemical test detailed.pptxabhijeetpadhi001
 
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxEPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxRaymartEstabillo3
 
Introduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher EducationIntroduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher Educationpboyjonauth
 

Recently uploaded (20)

CELL CYCLE Division Science 8 quarter IV.pptx
CELL CYCLE Division Science 8 quarter IV.pptxCELL CYCLE Division Science 8 quarter IV.pptx
CELL CYCLE Division Science 8 quarter IV.pptx
 
Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...Procuring digital preservation CAN be quick and painless with our new dynamic...
Procuring digital preservation CAN be quick and painless with our new dynamic...
 
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdfTataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
 
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
 
Final demo Grade 9 for demo Plan dessert.pptx
Final demo Grade 9 for demo Plan dessert.pptxFinal demo Grade 9 for demo Plan dessert.pptx
Final demo Grade 9 for demo Plan dessert.pptx
 
ESSENTIAL of (CS/IT/IS) class 06 (database)
ESSENTIAL of (CS/IT/IS) class 06 (database)ESSENTIAL of (CS/IT/IS) class 06 (database)
ESSENTIAL of (CS/IT/IS) class 06 (database)
 
Like-prefer-love -hate+verb+ing & silent letters & citizenship text.pdf
Like-prefer-love -hate+verb+ing & silent letters & citizenship text.pdfLike-prefer-love -hate+verb+ing & silent letters & citizenship text.pdf
Like-prefer-love -hate+verb+ing & silent letters & citizenship text.pdf
 
MARGINALIZATION (Different learners in Marginalized Group
MARGINALIZATION (Different learners in Marginalized GroupMARGINALIZATION (Different learners in Marginalized Group
MARGINALIZATION (Different learners in Marginalized Group
 
Presiding Officer Training module 2024 lok sabha elections
Presiding Officer Training module 2024 lok sabha electionsPresiding Officer Training module 2024 lok sabha elections
Presiding Officer Training module 2024 lok sabha elections
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERP
 
AmericanHighSchoolsprezentacijaoskolama.
AmericanHighSchoolsprezentacijaoskolama.AmericanHighSchoolsprezentacijaoskolama.
AmericanHighSchoolsprezentacijaoskolama.
 
Model Call Girl in Bikash Puri Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Bikash Puri  Delhi reach out to us at 🔝9953056974🔝Model Call Girl in Bikash Puri  Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Bikash Puri Delhi reach out to us at 🔝9953056974🔝
 
Alper Gobel In Media Res Media Component
Alper Gobel In Media Res Media ComponentAlper Gobel In Media Res Media Component
Alper Gobel In Media Res Media Component
 
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdfEnzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
 
Organic Name Reactions for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions  for the students and aspirants of Chemistry12th.pptxOrganic Name Reactions  for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions for the students and aspirants of Chemistry12th.pptx
 
OS-operating systems- ch04 (Threads) ...
OS-operating systems- ch04 (Threads) ...OS-operating systems- ch04 (Threads) ...
OS-operating systems- ch04 (Threads) ...
 
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
 
MICROBIOLOGY biochemical test detailed.pptx
MICROBIOLOGY biochemical test detailed.pptxMICROBIOLOGY biochemical test detailed.pptx
MICROBIOLOGY biochemical test detailed.pptx
 
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxEPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
 
Introduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher EducationIntroduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher Education
 

Autumn collection JavaOne 2014

  • 1. @JosePaumard #J1LBDS Autumn Collections From Iterable to Lambdas, Streams and Collectors
  • 3. @JosePaumard #J1LBDS Published November 10, 1994
  • 4. @JosePaumard #J1LBDS Still available hardover, paperback, multimedia CD Published November 10, 1994
  • 5. #J1LBDS @JosePaumard Why were they introduced ?
  • 6. #J1LBDS @JosePaumard Why were they introduced ? How will they change the way we build applications ?
  • 11. #J1LBDS @JosePaumard Let’s introduce the lambdas
  • 12. #J1LBDS @JosePaumard Let’s introduce the lambdas on a simple example
  • 13. #J1LBDS @JosePaumard A very simple example public class Person { private String name ; private int age ; // constructors // getters / setters } List<Person> list = new ArrayList<>() ; A plain old bean… … and a good old list
  • 14. #J1LBDS @JosePaumard int sum = 0 ; // I need a default value in case // the list is empty int average = 0 ; for (Person person : list) { sum += person.getAge() ; } if (!list.isEmpty()) { average = sum / list.size() ; } Average of the ages
  • 15. #J1LBDS @JosePaumard int sum = 0 ; int n = 0 ; int average = 0 ; for (Person person : list) { if (person.getAge() > 20) { n++ ; sum += person.getAge() ; } } if (n > 0) { average = sum / n ; } Trickier : average of the ages of people older than 20
  • 16. #J1LBDS @JosePaumard Trickier : average of the ages of people older than 20 « imperative programming » int sum = 0 ; int n = 0 ; int average = 0 ; for (Person person : list) { if (person.getAge() > 20) { n++ ; sum += person.getAge() ; } } if (n > 0) { average = sum / n ; }
  • 17. #J1LBDS @JosePaumard select avg(age) from Person where age > 20 … it does not have to be like that ! This is a description of the result
  • 18. #J1LBDS @JosePaumard … it does not have to be like that ! This is a description of the result In that case, the DB server is free to compute the result the way it sees fit © SQL language, 1974 select avg(age) from Person where age > 20
  • 19. #J1LBDS @JosePaumard Person age age > 20 sum 1st step : mapping map
  • 20. #J1LBDS @JosePaumard Person age age > 20 sum 1st step : mapping Mapping : -takes a list of a given type -gives another list of a different type -same number of elements map
  • 21. #J1LBDS @JosePaumard Person age age > 20 sum 2nd step : filtering filter map
  • 22. #J1LBDS @JosePaumard Person age age > 20 sum 2nd step : filtering Filtering : -takes a list of a given type -gives another list of a the same type -less elements filter map
  • 23. #J1LBDS @JosePaumard Person age age > 20 sum 3rd step : reduction reduce filter map
  • 24. #J1LBDS @JosePaumard Person age age > 20 sum 3rd step : reduction Reduction : agregation of all the elements in a single one Ex : average, sum, min, max, etc… reduce filter map
  • 25. #J1LBDS @JosePaumard How can I model that ?
  • 26. #J1LBDS @JosePaumard The JDK 7 way Create an interface to model the mapper… public interface Mapper<T, V> { public V map(T t) ; }
  • 27. #J1LBDS @JosePaumard Mapper<Person, Integer> mapper = new Mapper<Person, Integer>() { public Integer map(Person p) { return p.getAge() ; } } The JDK 7 way … and create an implementation public interface Mapper<T, V> { public V map(T t) ; }
  • 28. #J1LBDS @JosePaumard Predicate<Integer> predicate = new Predicate<Integer>() { public boolean filter(Integer age) { return age > 20 ; } } The JDK 7 way We can do the same for filtering public interface Predicate<T> { public boolean filter(T t) ; }
  • 29. #J1LBDS @JosePaumard Reducer<Integer> reduction = new Reducer<Integer>() { public Integer reduce(Integer i1, Integer i2) { return i1 + i2 ; } } The JDK 7 way And for the reduction public interface Reducer<T> { public T reduce(T t1, T t2) ; }
  • 30. #J1LBDS @JosePaumard The JDK 7 way So the whole map / filter / reduce looks like this 1)Create 3 interfaces public interface Mapper<T, V> { public V map(T t) ; } public interface Predicate<T> { public boolean filter(T t) ; } public interface Reducer<T> { public T reduce(T t1, T t2) ; }
  • 31. #J1LBDS @JosePaumard The JDK 7 way So the whole map / filter / reduce looks like this 1)Create 3 interfaces 2)Apply the pattern List<Person> persons = ... ; int sum = persons.map( new Mapper<Person, Integer>() { public Integer map(Person p) { return p.getAge() ; } }) .filter( new Filter<Integer>() { public boolean filter(Integer age) { return age > 20 ; } }) .reduce(0, new Reducer<Integer>() { public Integer reduce(Integer i1, Integer i2) { return i1 + i2 ; } } }) ;
  • 32. #J1LBDS @JosePaumard The JDK 7 way So the whole map / filter / reduce looks like this 1)Create 3 interfaces 2)Apply the pattern List<Person> persons = ... ; int sum = persons.map( new Mapper<Person, Integer>() { public Integer map(Person p) { return p.getAge() ; } }) .filter( new Filter<Integer>() { public boolean filter(Integer age) { return age > 20 ; } }) .reduce(0, new Reducer<Integer>() { public Integer reduce(Integer i1, Integer i2) { return i1 + i2 ; } } }) ;
  • 34. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { return person.getAge() ; } }
  • 35. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } }
  • 36. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } } mapper = (Person person) we take a person p
  • 37. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } } mapper = (Person person) -> and then …
  • 38. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } } mapper = (Person person) -> person.getAge() ; … return the age of person
  • 39. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } } mapper = (Person person) -> person.getAge() ;
  • 40. #J1LBDS @JosePaumard The JDK 8 way Let’s rewrite our mapper The compiler can recognize this as an implementation of Mapper mapper = new Mapper<Person, Integer>() { public Integer map(Person person) { // 1 method return person.getAge() ; } } mapper = (Person person) -> person.getAge() ;
  • 42. #J1LBDS @JosePaumard What if … … there is more than one statement ? The return has to be explicit mapper = (Person person) -> { System.out.println("Mapping " + person) ; return person.getAge() ; }
  • 43. #J1LBDS @JosePaumard What if … …I have no return value ? consumer = (Person person) -> p.setAge(p.getAge() + 1) ;
  • 44. #J1LBDS @JosePaumard …I have more than one argument ? Or : reducer = (int i1, int i2) -> { return i1 + i2 ; } What if … reducer = (int i1, int i2) -> i1 + i2 ;
  • 45. #J1LBDS @JosePaumard The JDK 8 way How can the compiler recognize the implementation of Mapper ? mapper = (Person person) -> person.getAge() ;
  • 46. #J1LBDS @JosePaumard The JDK 8 way How can the compiler recognize the implementation of Mapper ? 1)mapper is of type Mapper mapper = (Person person) -> person.getAge() ;
  • 47. #J1LBDS @JosePaumard The JDK 8 way How can the compiler recognize the implementation of Mapper ? 1)mapper is of type Mapper 2)There is only one method in Mapper mapper = (Person person) -> person.getAge() ;
  • 48. #J1LBDS @JosePaumard The JDK 8 way How can the compiler recognize the implementation of Mapper ? 1)mapper is of type Mapper 2)There is only one method in Mapper 3)Both the parameters and the return types are compatible mapper = (Person person) -> person.getAge() ;
  • 49. #J1LBDS @JosePaumard The JDK 8 way How can the compiler recognize the implementation of Mapper ? 1)mapper is of type Mapper 2)There is only one method in Mapper 3)Both the parameters and the return types are compatible 4)Thrown exceptions (if any are compatible) mapper = (Person person) -> person.getAge() ;
  • 50. #J1LBDS @JosePaumard The JDK 8 way How can the compiler recognize the implementation of Mapper ? 1)mapper is of type Mapper 2)There is only one method in Mapper 3)Both the parameters and the return types are compatible 4)Thrown exceptions (if any are compatible) mapper = (Person person) -> person.getAge() ;
  • 51. #J1LBDS @JosePaumard More lambdas Writing more lambdas becomes natural : mapper = (Person person) -> person.getAge() ; // mapper filter = (int age) -> age > 20 ; // filter reducer = (int i1, int i2) -> i1 + i2 ; // reducer
  • 52. #J1LBDS @JosePaumard More lambdas And most of the time, the compiler understands this : The « parameter types » can be omitted mapper = person -> person.getAge() ; // mapper filter = age -> age > 20 ; // filter reducer = (i1, i2) -> i1 + i2 ; // reducer
  • 53. #J1LBDS @JosePaumard Just a remark on the reduction How does it really work ?
  • 64. #J1LBDS @JosePaumard Reduction Examples : Reducer r1 = (i1, i2) -> i1 + i2 ; // Ok
  • 65. #J1LBDS @JosePaumard Reduction Examples : Reducer r1 = (i1, i2) -> i1 + i2 ; // Ok Reducer r2 = (i1, i2) -> i1*i1 + i2*i2 ; // Oooops Reducer r3 = (i1, i2) -> (i1 + i2)*(i1 + i2) ; // Aaaargh
  • 66. #J1LBDS @JosePaumard Reduction Examples : Caveat : the result is always reproductible in serial it’s not in parallel Reducer r1 = (i1, i2) -> i1 + i2 ; // Ok Reducer r2 = (i1, i2) -> i1*i1 + i2*i2 ; // Oooops Reducer r3 = (i1, i2) -> (i1 + i2)*(i1 + i2) ; // Aaaargh Reducer r4 = (i1, i2) -> (i1 + i2) / 2 ; // Ouch !!
  • 67. #J1LBDS @JosePaumard So far A lambda expression is an alternative to write instances of anonymous inner classes
  • 68. #J1LBDS @JosePaumard Other syntaxes Very often one writes mapper = person -> person.getAge() ;
  • 69. #J1LBDS @JosePaumard Other syntaxes Very often one writes But this syntax is also possible : « method reference » mapper = Person::getAge ; // non static method mapper = person -> person.getAge() ;
  • 70. #J1LBDS @JosePaumard Other example : Or : sum = (i1, i2) -> i1 + i2 ; sum = Integer::sum ; // static method, new ! Other syntaxes max = (i1, i2) -> i1 > i2 ? i1 : i2 ; max = Integer::max ; // static method, new !
  • 71. #J1LBDS @JosePaumard Other syntaxes Other example : toLower = String::toLowerCase ; // !!!! NO NO NO !!!! toLowerFR = String::toLowerCase(Locale.FRANCE) ;
  • 72. #J1LBDS @JosePaumard More on the lambdas
  • 73. #J1LBDS @JosePaumard 3 Questions about lambdas : What model for a lambda ?
  • 74. #J1LBDS @JosePaumard 3 Questions about lambdas : What model for a lambda ? Can I put a lambda in a variable ?
  • 75. #J1LBDS @JosePaumard 3 Questions about lambdas : What model for a lambda ? Can I put a lambda in a variable ? Is a lambda an object ?
  • 76. #J1LBDS @JosePaumard Modelization A lambda is an instance of a « functional interface » @FunctionalInterface public interface Consumer<T> { public void accept(T t) ; }
  • 77. #J1LBDS @JosePaumard Modelization A lambda is an instance of a « functional interface » -only one abstract method (methods from Object dont count) -can be annotated by @FunctionalInterface (optional) @FunctionalInterface public interface Consumer<T> { public void accept(T t) ; }
  • 78. #J1LBDS @JosePaumard Putting a lambda in a variable Example of a consumer So : Consumer<String> c = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s) ; } } ; Consumer<String> c = s -> System.out.println(s) ;
  • 79. #J1LBDS @JosePaumard Putting a lambda in a variable Example of a consumer So : Consumer<String> c = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s) ; } } ; Consumer<String> c = System.out::println ;
  • 80. #J1LBDS @JosePaumard Questions : What model for a lambda ? answer : with a functional interface Can I put a lambda in a variable ? answer : yes Is a lambda an object ?
  • 81. #J1LBDS @JosePaumard Is a lambda an objet ? Let’s play the game of 7 errors (with only 1 error) Consumer<String> c = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s) ; } } ; Consumer<String> c = s -> System.out.println(s) ;
  • 82. #J1LBDS @JosePaumard Is a lambda an objet ? Let’s play the game of 7 errors (with only 1 error) Consumer<String> c = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s) ; } } ; Consumer<String> c = s -> System.out.println(s) ;
  • 83. #J1LBDS @JosePaumard Questions : What model for a lambda ? answer : with a functionnal interface Can I put a lambda in a variable ? answer : yes Is a lambda an object ? answer : no
  • 84. #J1LBDS @JosePaumard Plenty of lambdas : java.util.function
  • 85. #J1LBDS @JosePaumard Java.util.functions This new package holds the functionnal interfaces There are 43 of them
  • 86. #J1LBDS @JosePaumard Java.util.functions Supplier : alone in its kind Consumer / BiConsumer Function / BiFunction (UnaryOperator / BinaryOperator) Predicate / BiPredicate Plus the primitive types versions
  • 87. #J1LBDS @JosePaumard Supplier A supplier supplies an object public interface Supplier<T> { T get() ; }
  • 88. #J1LBDS @JosePaumard Consumer A consumer just … accepts an object public interface Consumer<T> { void accept(T t) ; }
  • 89. #J1LBDS @JosePaumard Function A function takes an object and returns another one Can be chained and / or composed public interface Function<T, R> { R apply(T t) ; }
  • 90. #J1LBDS @JosePaumard Predicate A Predicate takes an object and returns a boolean Can be negated, composed with and / or public interface Predicate<T> { boolean test(T t) ; }
  • 91. #J1LBDS @JosePaumard Back to the map / filter / reduce pattern
  • 92. #J1LBDS @JosePaumard The JDK 7 way How to apply map / filter / reduce to List<Person> ?
  • 93. #J1LBDS @JosePaumard The JDK 7 way How to apply map / filter / reduce to List<Person> ? The legal way is to iterate over the elements and apply the pattern
  • 94. #J1LBDS @JosePaumard The JDK 7 way How to apply map / filter / reduce to List<Person> ? The legal way is to iterate over the elements and apply the pattern One can create a helper method
  • 95. #J1LBDS @JosePaumard Applying map to a List With a helper method, JDK 7 List<Person> persons = new ArrayList<>() ; List<Integer> ages = // ages is a new list Lists.map( persons, new Mapper<Person, Integer>() { public Integer map(Person p) { return p.getAge() ; } } ) ;
  • 96. #J1LBDS @JosePaumard Applying map to a List With a helper method, JDK 8 & lambdas List<Person> persons = new ArrayList<>() ; List<Integer> ages = Lists.map( persons, person -> person.getAge() ) ;
  • 97. #J1LBDS @JosePaumard Applying map to a List With a helper method, JDK 8 & lambdas List<Person> persons = new ArrayList<>() ; List<Integer> ages = Lists.map( persons, Person::getAge ) ;
  • 98. #J1LBDS @JosePaumard Putting things together The map / filter / reduce pattern would look like this // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 99. #J1LBDS @JosePaumard Putting things together The map / filter / reduce pattern would look like this The idea is to push lambdas to the API, and let it apply them on its content // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 100. #J1LBDS @JosePaumard Putting things together The map / filter / reduce pattern would look like this Pro : the API can be optimized without touching the code : great ! // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 101. #J1LBDS @JosePaumard Putting things together The map / filter / reduce pattern would look like this Pro : the API can be optimized without touching the code Cons … // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 102. #J1LBDS @JosePaumard Putting things together 1) Suppose persons is a really BIG list // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 103. #J1LBDS @JosePaumard Putting things together 1) Suppose persons is a really BIG list 2 duplications : ages & agesGT20 // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 104. #J1LBDS @JosePaumard Putting things together 1) Suppose persons is a really BIG list 2 duplications : ages & agesGT20 What do we do with them ? Send them to the GC // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 105. #J1LBDS @JosePaumard Putting things together 2) Suppose we have a allMatch() reducer allMatch is true if all the names are shorter than 20 chars let’s see a possible implementation of allMatch() // applying the map / filter / reduce pattern List<Person> persons = ... ; List<String> names = Lists.map(persons, p -> p.getName()) ; boolean allMatch = Lists.allMatch(names, n -> n.length() < 20) ;
  • 106. #J1LBDS @JosePaumard How could one write allMatch ? Here is a basic implementation of allMatch public static <T> boolean allMatch( List<? extends T> list, Filter<T> filter) { for (T t : list) { if (!filter.filter(t)) { return false ; } } return true ; }
  • 107. #J1LBDS @JosePaumard How could one write allMatch ? Here is a basic implementation of allMatch public static <T> boolean allMatch( List<? extends T> list, Filter<T> filter) { for (T t : list) { if (!filter.filter(t)) { return false ; } } return true ; } No need to iterate over the whole list
  • 108. #J1LBDS @JosePaumard Putting things together When we apply the allMatch() reducer… … the list names has already been evaluated ! // applying the map / filter / reduce pattern List<Person> persons = ... ; List<String> names = Lists.map(persons, p -> p.getName()) ; boolean allMatch = Lists.allMatch(names, n -> n.length() < 20) ;
  • 109. #J1LBDS @JosePaumard Putting things together When we apply the allMatch() reducer… … the list names has already been evaluated ! We lost a big opportunity for optimization ! // applying the map / filter / reduce pattern List<Person> persons = ... ; List<String> names = Lists.map(persons, p -> p.getName()) ; boolean allMatch = Lists.allMatch(names, n -> n.length() < 20) ;
  • 110. #J1LBDS @JosePaumard Putting things together When we apply the allMatch() reducer… … we should have wait to apply the filter A good way to do that : apply the filter step lazily ! // applying the map / filter / reduce pattern List<Person> persons = ... ; List<String> names = Lists.map(persons, p -> p.getName()) ; boolean allMatch = Lists.allMatch(names, n -> n.length() < 20) ;
  • 111. #J1LBDS @JosePaumard Conclusion Pro : 1 Cons : 3 (at least) // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 112. #J1LBDS @JosePaumard Conclusion Pro : 1 Cons : 3 (at least) // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = Lists.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = Lists.filter(ages, a -> a > 20) ; int sum = Lists.reduce(agesGT20, Integer::sum) ;
  • 113. #J1LBDS @JosePaumard Conclusion And the same goes for this one // applying the map / filter / reduce pattern List<Person> persons = ... ; List<Integer> ages = persons.map( persons, p -> p.getAge()) ; List<Integer> agesGT20 = ages.filter(ages, a -> a > 20) ; int sum = agesGT20.reduce(agesGT20, Integer::sum) ;
  • 114. #J1LBDS @JosePaumard What about « in place » operations ? Not possible for the map step, because the type of the list changes Could be evaluated for the filter, with concurrency issues Doesnt make sense for the reduction
  • 115. #J1LBDS @JosePaumard Conclusion (again) We need a new concept to handle BIG lists efficiently
  • 116. #J1LBDS @JosePaumard Conclusion (again) We need a new concept to handle BIG lists efficiently The Collection framework is not the right one…
  • 117. #J1LBDS @JosePaumard Conclusion (again) We need a new concept to handle BIG lists efficiently The Collection framework is not the right one We need something else !
  • 118. #J1LBDS @JosePaumard So what pattern to choose ?
  • 119. #J1LBDS @JosePaumard Introduction Putting map / filter / reduce methods on Collection would have led to : And even if it doesnt lead to viable patterns, it is still a pleasant way of writing things // map / filter / reduce pattern on collections int sum = persons .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ;
  • 120. #J1LBDS @JosePaumard Introduction Let’s keep the same kind of pattern and add a stream() // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ;
  • 121. #J1LBDS @JosePaumard Introduction Collection.stream() returns a Stream : new interface New interface = our hands are free ! // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ;
  • 122. #J1LBDS @JosePaumard New Collection interface So we need a new method on Collection public interface Collection<E> { // our good old methods Stream<E> stream() ; }
  • 123. #J1LBDS @JosePaumard New Collection interface Problem : ArrayList doesnt compile anymore… Something has to be done ! public interface Collection<E> { // our good old methods Stream<E> stream() ; }
  • 124. #J1LBDS @JosePaumard Interfaces We need to be able to add methods on interfaces… … without providing the implementation in the implementing classes!
  • 125. #J1LBDS @JosePaumard Interfaces We need to be able to add methods on interfaces… … without providing the implementation in the implementing classes! Not possible in Java 7
  • 126. #J1LBDS @JosePaumard Interfaces We need to be able to add methods on interfaces… … without providing the implementation in the implementing classes! Not possible in Java 7 Solution: change the way interfaces work in Java
  • 128. #J1LBDS @JosePaumard Java 8 interfaces ArrayList needs to know the implementation of stream()… public interface Collection<E> { // our good old methods Stream<E> stream() ; }
  • 129. #J1LBDS @JosePaumard Java 8 interfaces Let’s put it in the interface ! public interface Collection<E> { // our good old methods default Stream<E> stream() { return ... ; } }
  • 130. #J1LBDS @JosePaumard Java 8 interfaces Let’s introduce default methods in Java Default methods are about interface evolution Allows the extension of old interfaces public interface Collection<E> { // our good old methods default Stream<E> stream() { return ... ; } }
  • 131. #J1LBDS @JosePaumard Interfaces vs Abstract classes Does an interface become the same as an abstract class ?
  • 132. #J1LBDS @JosePaumard Interfaces vs Abstract classes Does an interface become the same as an abstract class ? No! -an abstract class can have field, ie a state -an abstract class has a constructor
  • 133. #J1LBDS @JosePaumard Default methods Does it bring multiple inheritance to Java ?
  • 134. #J1LBDS @JosePaumard Default methods Does it bring multiple inheritance to Java ? Yes ! But we already have it
  • 135. #J1LBDS @JosePaumard Default methods Does it bring multiple inheritance to Java ? Yes ! But we already have it public class String implements Serializable, Comparable<String>, CharSequence { // ... }
  • 136. #J1LBDS @JosePaumard Default methods What we have so far is multiple inheritance of type
  • 137. #J1LBDS @JosePaumard Default methods What we have so far is multiple inheritance of type What we get in Java 8 is multiple inheritance of behavior
  • 138. #J1LBDS @JosePaumard Default methods What we have so far is multiple inheritance of type What we get in Java 8 is multiple inheritance of behavior What we dont have is multiple inheritance of state
  • 139. #J1LBDS @JosePaumard Default methods What we have so far is multiple inheritance of type What we get in Java 8 is multiple inheritance of behavior What we dont have is multiple inheritance of state … and this is where the trouble is !
  • 140. #J1LBDS @JosePaumard Default methods Will we have conflicts ?
  • 141. #J1LBDS @JosePaumard Default methods Will we have conflicts ? Yes, so we need rules to handle them
  • 142. #J1LBDS @JosePaumard Default methods public class C implements A, B { // ... }
  • 143. #J1LBDS @JosePaumard Default methods Example #1 public interface A { default String a() { ... } } public interface B { default String a() { ... } } public class C implements A, B { // ... }
  • 144. #J1LBDS @JosePaumard Default methods Example #1 Compile time error : class C inherits unrelated defaults for a() from types A and B public interface A { default String a() { ... } } public interface B { default String a() { ... } } public class C implements A, B { // ... }
  • 145. #J1LBDS @JosePaumard Default methods Rule #1 Class wins ! No default if an implementation is present public interface A { default String a() { ... } } public interface B { default String a() { ... } } public class C implements A, B { public String a() { ... } }
  • 146. #J1LBDS @JosePaumard Default methods Rule #2 A is more specific than B : A.a() is chosen public interface A extends B { default String a() { ... } } public interface B { default String a() { ... } } public class C implements A, B { // ... }
  • 147. #J1LBDS @JosePaumard Default methods Back to rule #1 We can also make an explicit call public class C implements A, B { public String a() { return B.super(a) ; } } public interface A { default String a() { ... } } public interface B { default String a() { ... } }
  • 148. #J1LBDS @JosePaumard 2 simple rules To handle the conflict of multiple inheritance of behavior
  • 149. #J1LBDS @JosePaumard 2 simple rules To handle the conflict of multiple inheritance of behavior 1)Class wins !
  • 150. #J1LBDS @JosePaumard 2 simple rules To handle the conflict of multiple inheritance of behavior 1)Class wins ! 2)More specific interfaces wins over less specific
  • 151. #J1LBDS @JosePaumard 2 simple rules To handle the conflict of multiple inheritance of behavior 1)Class wins ! 2)More specific interfaces wins over less specific
  • 152. #J1LBDS @JosePaumard An example Everybody who writes an implementation of Iterator writes this : public class MyIterator implements Iterator<E> { // some critical business code public void remove() { throw new UnsupportedOperationException("Naah !!!!!!") ; } ; }
  • 153. #J1LBDS @JosePaumard An example Thanks to Java 8 : No silly implementation of remove() anymore ! public interface Iterator<E> { default void remove() { throw new UnsupportedOperationException("remove") ; } ; }
  • 154. #J1LBDS @JosePaumard So the concept of « interface » changed in Java 8 public class HelloWorld { // souvenir souvenir public static void main(String[] args) { System.out.println("Hello world!") ; } ; } Java 8 interfaces
  • 155. #J1LBDS @JosePaumard Java 8 interfaces So the concept of « interface » changed in Java 8 I mean, really public interface HelloWorld { // souvenir souvenir public static void main(String[] args) { System.out.println("Hello world!") ; } ; }
  • 156. #J1LBDS @JosePaumard Java 8 interfaces 1)Default methods, multiple behavior inheritance Rules to handle conflicts, solved at compile time 2)Static methods in interfaces Will bring new patterns and new ways to write APIs
  • 157. #J1LBDS @JosePaumard Where are we ? 1)We have a new syntax 2)We have a new pattern to implement 3)We have new interfaces to keep the backward compatibily
  • 159. #J1LBDS @JosePaumard What is a Stream From a technical point of view : a typed interface « a stream of String »
  • 160. #J1LBDS @JosePaumard What is a Stream From a technical point of view : a typed interface Other classes for primitive types : « a stream of String » IntStream, LongStream, DoubleStream
  • 161. #J1LBDS @JosePaumard It’s a new notion It looks like a collection, but… -It is built on a « source », that can be a collection -No data needs to be provided at build time -No limit on what the source can produce
  • 162. #J1LBDS @JosePaumard It’s a new notion A stream can be built on : -A collection or an array -An iterator -An I/O source Some of those can be « infinite »
  • 163. #J1LBDS @JosePaumard It’s a new notion 1)A stream doesnt hold any data It’s just an object on which one can declare operations Streams are about « specifying computations »
  • 164. #J1LBDS @JosePaumard It’s a new notion 1)A stream doesnt hold any data 2)A stream cant modify its source Consequence : it can use parallel processing
  • 165. #J1LBDS @JosePaumard It’s a new notion 1)A stream doesnt hold any data 2)A stream cant modify its source 3)A source can be infinite So we need a way to guarantee that computations will be conducted in finite time
  • 166. #J1LBDS @JosePaumard It’s a new notion 1)A stream doesnt hold any data 2)A stream cant modify its source 3)A source can be infinite 4)A stream works lazily Then optimizations can be made among the different operations We need a way / convention to trigger the computations
  • 167. #J1LBDS @JosePaumard How can we build a stream ? Many ways… 1)From a collection : method Collection.stream Collection<String> collection = ... ; Stream<String> stream = collection.stream() ;
  • 168. #J1LBDS @JosePaumard How can we build a stream ? Many ways… 1)From a collection : method Collection.stream 2)From an array : Arrays.stream(Object []) Stream<String> stream2 = Arrays.stream(new String [] {"one", "two", "three"}) ;
  • 169. #J1LBDS @JosePaumard How can we build a stream ? Many ways… 1)From a collection : method Collection.stream 2)From an array : Arrays.stream(Object []) 3)From factory methods in Stream, IntStream, … Stream<String> stream1 = Stream.of("one", "two", "three") ;
  • 170. #J1LBDS @JosePaumard How can we build a stream ? Some last patterns Stream.empty() ; // returns an empty Stream Stream.of(T t) ; // a stream with a single element Stream.generate(Supplier<T> s) ; Stream.iterate(T seed, UnaryOperator<T> f) ;
  • 171. #J1LBDS @JosePaumard How can we build a stream ? Other ways scattered in the JDK string.chars() ; // returns a IntStream lineNumberReader.lines() ; // returns a Stream<String> random.ints() ; // return a IntStream
  • 172. #J1LBDS @JosePaumard Back to our map / filter / reduce example // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ; A 1st example Builds a stream on a List
  • 173. #J1LBDS @JosePaumard A 1st example Back to our map / filter / reduce example // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ; Declares operations
  • 174. #J1LBDS @JosePaumard A 1st example Back to our map / filter / reduce example // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ; Triggers the computation
  • 175. #J1LBDS @JosePaumard A 1st example Back to our map / filter / reduce example // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ; Default value, in case the stream is empty
  • 176. #J1LBDS @JosePaumard 3 things on Streams
  • 177. #J1LBDS @JosePaumard 1) Two types of operations One can declare operations on a Stream Two types of operations : 1)Intermediate operations : declarations, processed lazily ex : map, filter
  • 178. #J1LBDS @JosePaumard 1) Two types of operations One can declare operations on a Stream Two types of operations : 1)Intermediate operations : declarations, processed lazily ex : map, filter 2)Terminal operations : trigger the computations ex : reduce
  • 179. #J1LBDS @JosePaumard 2) State of a stream The implementation of Stream has a state : -SIZED : the number of elements is known -ORDERED : the order matters (List) -DISTINCT : all elements are unique (Set) -SORTED : all elements have been sorted (SortedSet)
  • 180. #J1LBDS @JosePaumard 2) State of a stream Some operations change that : -filtering removes the SIZED -mapping removes DISTINCT and SORTED
  • 181. #J1LBDS @JosePaumard 2) State of a stream It’s all about optimization! Collection<Person> collection = ... ; Stream<Person> stream = collection.stream() ; stream.distinct() .map(Person::getAge) .filter(a -> a > 20) .reduce(0, Integer::sum) ;
  • 182. #J1LBDS @JosePaumard 2) State of a stream It’s all about optimization! Collection<Person> collection = new HashSet<>() ; Stream<Person> stream = collection.stream() ; // DISTINCT stream.distinct() // DISTINCT = will not do anything .map(Person::getAge) .filter(a -> a > 20) .reduce(0, Integer::sum) ;
  • 183. #J1LBDS @JosePaumard 2) State of a stream It’s all about optimization! Collection<Person> collection = ... ; Stream<Person> stream = collection.stream() ; stream.sorted() .forEach(System.out::println) ;
  • 184. #J1LBDS @JosePaumard 2) State of a stream It’s all about optimization! Collection<Person> collection = new SortedSet<>() ; Stream<Person> stream = collection.stream() ; // SORTED stream.sorted() // SORTED = doesnt do anything .forEach(System.out::println) ;
  • 185. #J1LBDS @JosePaumard 3) Stateless / stateful operations Stateless / stateful operations Some operations are stateless : It means that they dont need more information than the one held by their parameters persons.stream().map(p -> p.getAge()) ;
  • 186. #J1LBDS @JosePaumard 3) Stateless / stateful operations Stateless / stateful operations Some operations are stateless : Some needs to retain information : persons.stream().map(p -> p.getAge()) ; stream.limit(10_000_000) ; // select the 10M first elements
  • 187. #J1LBDS @JosePaumard Example Let’s sort an array of String Random rand = new Random() ; String [] strings = new String[10_000_000] ; for (int i = 0 ; i < strings.length ; i++) { strings[i] = Long.toHexString(rand.nextLong()) ; }
  • 188. #J1LBDS @JosePaumard Example Let’s sort an array of String Soooo Java 7… Random rand = new Random() ; String [] strings = new String[10_000_000] ; for (int i = 0 ; i < strings.length ; i++) { strings[i] = Long.toHexString(rand.nextLong()) ; }
  • 189. #J1LBDS @JosePaumard Example Let’s sort an array of String Better ? Random rand = new Random() ; Stream<String> stream = Stream.generate( () -> Long.toHexString(rand.nextLong()) ) ;
  • 190. #J1LBDS @JosePaumard Let’s sort an array of String Better ! // Random rand = new Random() ; Stream<String> stream = Stream.generate( () -> Long.toHexString(ThreadLocalRandom.current().nextLong()) ) ; Example
  • 191. #J1LBDS @JosePaumard Let’s sort an array of String Example // other way Stream<String> stream = ThreadLocalRandom .current() .longs() // returns a LongStream .mapToObj(l -> Long.toHexString(l)) ;
  • 192. #J1LBDS @JosePaumard Let’s sort an array of String Example // other way Stream<String> stream = ThreadLocalRandom .current() .longs() .mapToObj(Long::toHexString) ;
  • 193. #J1LBDS @JosePaumard Let’s sort an array of String Example // other way Stream<String> stream = ThreadLocalRandom .current() .longs() .mapToObj(Long::toHexString) .limit(10_000_000) .sorted() ; T = 4 ms
  • 194. #J1LBDS @JosePaumard Let’s sort an array of String Example // other way Stream<String> stream = ThreadLocalRandom .current() .longs() .mapToObj(Long::toHexString) .limit(10_000_000) .sorted() ; Object [] sorted = stream.toArray() ;
  • 195. #J1LBDS @JosePaumard Let’s sort an array of String Example // other way Stream<String> stream = ThreadLocalRandom .current() .longs() .mapToObj(Long::toHexString) .limit(10_000_000) .sorted() ; Object [] sorted = stream.toArray() ; T = 14 s
  • 196. #J1LBDS @JosePaumard Let’s sort an array of String Example // other way Stream<String> stream = ThreadLocalRandom .current() .longs() .mapToObj(Long::toHexString) .limit(10_000_000) .sorted() ; Object [] sorted = stream.toArray() ; T = 14 s Intermediate calls !
  • 197. #J1LBDS @JosePaumard More on stream operations 1)There are intermediate and terminal operations 2)A stream is processed on a terminal operation call
  • 198. #J1LBDS @JosePaumard More on stream operations 1)There are intermediate and terminal operations 2)A stream is processed on a terminal operation call 3)Only one terminal operation is allowed 4)It cannot be processed again If needed another stream should be built on the source
  • 200. #J1LBDS @JosePaumard Optimization The first optimization (well, laziness was first !) we need is parallelism The fork / join enable parallel programming since JDK 7 But writing tasks is hard and does not always lead to better performances
  • 201. #J1LBDS @JosePaumard Optimization The first optimization (well, laziness was first !) we need is parallelism The fork / join enable parallel programming since JDK 7 But writing tasks is hard and does not always lead to better performances Using the parallel stream API is much more secure
  • 202. #J1LBDS @JosePaumard How to build a parallel stream ? Two patterns 1)Call parallelStream() instead of stream() 2)Call parallel() on an existing stream Stream<String> s = strings.parallelStream() ; Stream<String> s = strings.stream().parallel() ;
  • 203. #J1LBDS @JosePaumard Can we decide the # of cores ? Answer is yes, but it’s tricky System.setProperty( "java.util.concurrent.ForkJoinPool.common.parallelism", 2) ;
  • 204. #J1LBDS @JosePaumard Can we decide the # of cores ? Answer is yes, but it’s tricky List<Person> persons = ... ; ForkJoinPool fjp = new ForkJoinPool(2) ; fjp.submit( () -> // persons.stream().parallel() // .mapToInt(p -> p.getAge()) // Callable<Integer> .filter(age -> age > 20) // .average() // ).get() ;
  • 205. #J1LBDS @JosePaumard Is parallelism really that simple ? Example : performances Code 1 List<Long> list = new ArrayList<>(10_000_100) ; for (int i = 0 ; i < 10_000_000 ; i++) { list.add(ThreadLocalRandom.current().nextLong()) ; }
  • 206. #J1LBDS @JosePaumard Is parallelism really that simple ? Example : performances Code 2 Stream<Long> stream = Stream.generate(() -> ThreadLocalRandom.current().nextLong()) ; List<Long> list = stream.limit(10_000_000).collect(Collectors.toList()) ;
  • 207. #J1LBDS @JosePaumard Is parallelism really that simple ? Example : performances Code 3 Stream<Long> stream = ThreadLocalRandom.current().longs(10_000_000).mapToObj(Long::new) ; List<Long> list = stream.collect(Collectors.toList()) ;
  • 208. #J1LBDS @JosePaumard Is parallelism really that simple ? Example : performances Serial Parallel Code 1 (for) 270 ms Code 2 (limit) 310 ms Code 3 (longs) 250 ms
  • 209. #J1LBDS @JosePaumard Is parallelism really that simple ? Example : performances Serial Parallel Code 1 (for) 270 ms Code 2 (limit) 310 ms 500 ms Code 3 (longs) 250 ms 320 ms
  • 210. #J1LBDS @JosePaumard Is parallelism really that simple ? A sneaky problem List<Person> persons = new ArrayList<>() ; // some code to add people persons.stream() .map(Person::getAge) .collect(Collectors.toList()) ;
  • 211. #J1LBDS @JosePaumard Is parallelism really that simple ? A sneaky problem List<Person> persons = new ArrayList<>() ; // some code to add people persons.stream() // ORDERED ! .map(Person::getAge) .collect(Collectors.toList()) ;
  • 212. #J1LBDS @JosePaumard Is parallelism really that simple ? A sneaky problem List<Person> persons = new ArrayList<>() ; // some code to add people persons.stream() .parallel() .map(Person::getAge) .collect(Collectors.toList()) ;
  • 213. #J1LBDS @JosePaumard Is parallelism really that simple ? A sneaky problem List<Person> persons = new ArrayList<>() ; // some code to add people persons.stream() .unordered() .parallel() .map(Person::getAge) .collect(Collectors.toList()) ;
  • 214. #J1LBDS @JosePaumard Parallelism Parallelism implies overhead most of the time Badly configured parallel operations can lead to unneeded computations that will slow down the overall process Unnecessary ordering of a stream will lead to performance hits
  • 216. #J1LBDS @JosePaumard A simple reduction Sum of ages // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .reduce(0, (a1, a2) -> a1 + a2) ;
  • 217. #J1LBDS @JosePaumard It would be nice to be able to write : But there’s no sum() on Stream<T> What would be the sense of « adding persons » ? // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .sum() ; A simple reduction
  • 218. #J1LBDS @JosePaumard A simple reduction It would be nice to be able to write : But there’s no sum() on Stream<T> There’s one on IntStream ! // map / filter / reduce pattern on collections int sum = persons.stream() .map(p -> p.getAge()) .filter(a -> a > 20) .sum() ;
  • 219. #J1LBDS @JosePaumard A simple reduction 2nd version : Value if persons is an empty list : 0 // map / filter / reduce pattern on collections int sum = persons.stream() .map(Person::getAge) .filter(a -> a > 20) .mapToInt(Integer::intValue) .sum() ;
  • 220. #J1LBDS @JosePaumard A simple reduction 2nd version : Value if persons is an empty list : 0 // map / filter / reduce pattern on collections int sum = persons.stream() .mapToInt(Person::getAge) .filter(a -> a > 20) // .mapToInt(Integer::intValue) .sum() ;
  • 222. #J1LBDS @JosePaumard A simple reduction What about max() and min() ? How can one chose a default value ? // map / filter / reduce pattern on collections ....... = persons.stream() .mapToInt(Person::getAge) .filter(a -> a > 20) .max() ;
  • 223. #J1LBDS @JosePaumard Problem with the default value The « default value » is a tricky notion
  • 224. #J1LBDS @JosePaumard Problem with the default value The « default value » is a tricky notion 1)The « default value » is the reduction of the empty set
  • 225. #J1LBDS @JosePaumard Problem with the default value The « default value » is a tricky notion 1)The « default value » is the reduction of the empty set 2)But it’s also the identity element for the reduction
  • 234. #J1LBDS @JosePaumard Problem with the default value The « default value » is a tricky notion 1)The « default value » is the reduction of the empty set 2)But it’s also the identity element for the reduction
  • 235. #J1LBDS @JosePaumard Problem with the default value Problem : max() and min() have no identity element eg : an element e for which max(e, a) = a
  • 236. #J1LBDS @JosePaumard Problem with the default value Problem : max() and min() have no identity element eg : an element e for which max(e, a) = a 0 cant be, max(0, -1) is not -1…
  • 237. #J1LBDS @JosePaumard Problem with the default value Problem : max() and min() have no identity element eg : an element e for which max(e, a) = a 0 cant be, max(0, -1) is not -1… −∞ is not an integer
  • 238. #J1LBDS @JosePaumard Problem with the default value Problem : max() and min() have no identity element eg : an element e for which max(e, a) = a 0 cant be, max(0, -1) is not -1… −∞ is not an integer Integer.MIN_VALUE
  • 239. #J1LBDS @JosePaumard Problem with the default value So what is the default value of max() and min() ?
  • 240. #J1LBDS @JosePaumard Problem with the default value So what is the default value of max() and min() ? Answer : there is no default value for max() and min()
  • 241. #J1LBDS @JosePaumard Problem with the default value So what is the returned type of the max() method ? // map / filter / reduce pattern on collections ....... = persons.stream() .mapToInt(Person::getAge) .filter(a -> a > 20) .max() ;
  • 242. #J1LBDS @JosePaumard Problem with the default value So what is the returned type of the max() method ? If it’s int, then the default value will be 0… // map / filter / reduce pattern on collections ....... = persons.stream() .mapToInt(Person::getAge) .filter(a -> a > 20) .max() ;
  • 243. #J1LBDS @JosePaumard Problem with the default value So what is the returned type of the max() method ? If it’s Integer, then the default value will be null… // map / filter / reduce pattern on collections ....... = persons.stream() .mapToInt(Person::getAge) .filter(a -> a > 20) .max() ;
  • 244. #J1LBDS @JosePaumard Optionals Since there’s none, we need another notion « there might be no result » // map / filter / reduce pattern on collections OptionalInt optionalMax = persons.stream() .mapToInt(Person::getAge) .filter(a -> a > 20) .max() ;
  • 245. #J1LBDS @JosePaumard Optionals What can I do with OptionalInt ? 1st pattern : test if it holds a value OptionalInt optionalMax = ... ; int max ; if (optionalMax.isPresent()) { max = optionalMax.get() ; } else { max = ... ; // decide a « default value » }
  • 246. #J1LBDS @JosePaumard Optionals What can I do with OptionalInt ? 2nd pattern : read the held value, can get an exception OptionalInt optionalMax = ... ; // throws NoSuchElementException if no held value int max = optionalMax.getAsInt() ;
  • 247. #J1LBDS @JosePaumard Optionals What can I do with OptionalInt ? 3rd pattern : read the held value, giving a default value OptionalInt optionalMax = ... ; // get 0 if no held value int max = optionalMax.orElse(0) ;
  • 248. #J1LBDS @JosePaumard Optionals What can I do with OptionalInt ? 4th pattern : read the held value, or throw an exception OptionalInt optionalMax = ... ; // exceptionSupplier will supply an exception, if no held value int max = optionalMax.orElseThrow(exceptionSupplier) ;
  • 249. #J1LBDS @JosePaumard Available optionals Optional<T> OptionalInt, OptionalLong, OptionalDouble
  • 250. #J1LBDS @JosePaumard Available reductions On Stream<T> : -reduce(), with different parameters -count(), min(), max() -anyMatch(), allMatch(), noneMatch() -findFirst(), findAny() -toArray() -forEach(), forEachOrdered()
  • 251. #J1LBDS @JosePaumard Available reductions On IntStream, LongStream, DoubleStream : -average() -summaryStatistics()
  • 252. #J1LBDS @JosePaumard Available reductions SummaryStatistics is an object that holds : -Count, Min, Max, Sum, Average It’s a consumer, so it can be easily extended to compute other statistics
  • 254. #J1LBDS @JosePaumard Mutable reductions : example 1 Use of the helper class : Collectors List<String> strings = stream .map(Object::toString) .collect(Collectors.toList()) ;
  • 255. #J1LBDS @JosePaumard Mutable reductions : example 2 Concatenating strings with a helper String names = persons .stream() .map(Person::getName) .collect(Collectors.joining()) ;
  • 256. #J1LBDS @JosePaumard Mutable reductions Common things : -have a container : Collection or StringBuilder -have a way to add an element to the container -have a way to merge two containers (for parallelization)
  • 257. #J1LBDS @JosePaumard Mutable reductions : example 1 Putting things together : ArrayList<String> strings = stream .map(Object::toString) .collect( () -> new ArrayList<String>(), // the supplier (suppList, s) -> suppList.add(s), // the accumulator (suppL1, suppL2) -> suppL1.addAll(suppL2) // the combiner ) ;
  • 258. #J1LBDS @JosePaumard Mutable reductions : example 1 Putting things together : ArrayList<String> strings = stream .map(Object::toString) .collect( ArrayList::new, // the supplier ArrayList::add, // the accumulator ArrayList::addAll // the combiner ) ;
  • 259. #J1LBDS @JosePaumard Mutable reductions : example 1 Putting things together : ArrayList<String> strings = stream .map(Object::toString) .collect( Collectors.toList() ) ;
  • 261. #J1LBDS @JosePaumard The Collectors class A rich toolbox (37 methods) for various types of reductions -counting, minBy, maxBy -summing, averaging, summarizing -joining -toList, toSet And - mapping, groupingBy, partionningBy
  • 262. #J1LBDS @JosePaumard The Collectors class Average, Sum, Count persons .stream() .collect(Collectors.averagingDouble(Person::getAge)) ; persons .stream() .collect(Collectors.counting()) ;
  • 263. #J1LBDS @JosePaumard The Collectors class Concatenating the names in a String String names = persons .stream() .map(Person::getName) .collect(Collectors.joining(", ")) ;
  • 264. #J1LBDS @JosePaumard The Collectors class Accumulating in a List, Set Set<Person> setOfPersons = persons .stream() .collect( Collectors.toSet()) ;
  • 265. #J1LBDS @JosePaumard The Collectors class Accumulating in a custom collection TreeSet<Person> treeSetOfPersons = persons .stream() .collect( Collectors.toCollection(TreeSet::new)) ;
  • 266. #J1LBDS @JosePaumard The Collectors class Getting the max according to a comparator Bonus : new API to build comparators Optional<Person> optionalPerson = persons .stream() .collect( Collectors.maxBy( Comparator.comparing(Person::getAge)) ;
  • 267. #J1LBDS @JosePaumard Building comparators New API to build comparators in a declarative way Comparator<Person> comp = Comparator.comparing(Person::getLastName) .thenComparing(Person::getFirstName) .thenComparing(Person::getAge) ;
  • 268. #J1LBDS @JosePaumard Building comparators New API to build comparators in a declarative way Comparator<Person> comp = Comparator.comparing(Person::getLastName) .thenComparing(Person::getFirstName) .thenComparing(Person::getAge) ; Comparator<Person> comp = Comparator.comparing(Person::getLastName) .reversed() ;
  • 269. #J1LBDS @JosePaumard Building comparators New API to build comparators in a declarative way Comparator<Person> comp = Comparator.comparing(Person::getLastName) .thenComparing(Person::getFirstName) .thenComparing(Person::getAge) ; Comparator<Person> comp = Comparator.nullsFirst( Comparator.comparing(Person::getLastName) ) ;
  • 270. #J1LBDS @JosePaumard The Collector API : groupingBy « Grouping by » builds hash maps -must explain how the keys are built -by default the values are put in a list -may specify a downstream (ie a collector)
  • 271. #J1LBDS @JosePaumard The Collector API : groupingBy Grouping a list of persons by their age Map<Integer, List<Person>> map = persons .stream() .collect( Collectors.groupingBy(Person::getAge)) ;
  • 272. #J1LBDS @JosePaumard The Collector API : groupingBy Grouping a list of persons by their age Map<Integer, Set<Person>> map = persons .stream() .collect( Collectors.groupingBy( Person::getAge, Collectors.toSet() // the downstream ) ;
  • 273. #J1LBDS @JosePaumard The Collector API : groupingBy Grouping a list of persons names by their age Map<Integer, Set<String>> map = persons .stream() .collect( Collectors.groupingBy( Person::getAge, Collectors.mapping( // Person::getLastName, // the downstream Collectors.toSet() // ) ) ;
  • 274. #J1LBDS @JosePaumard The Collector API : groupingBy Grouping a list of persons names by their age Map<Integer, TreeSet<String>> map = persons .stream() .collect( Collectors.groupingBy( Person::getAge, Collectors.mapping( Person::getLastName, Collectors.toCollection(TreeSet::new) ) ) ;
  • 275. #J1LBDS @JosePaumard The Collector API : groupingBy Grouping a list of blah blah blah TreeMap<Integer, TreeSet<String>> map = persons .stream() .collect( Collectors.groupingBy( Person::getAge, TreeMap::new, Collectors.mapping( Person::getLastName, Collectors.toCollection(TreeSet::new) ) ) ;
  • 276. #J1LBDS @JosePaumard The Collector API : groupingBy Example : creating an age histogram Gives the # of persons by age Map<Integer, Long> map = persons .stream() .collect( Collectors.groupingBy(Person::getAge, Collectors.counting()) ) ;
  • 277. #J1LBDS @JosePaumard The Collector API : partioningBy Creates a Map<Boolean, …> on a predicate -the map has 2 keys : TRUE and FALSE -may specify a downstream
  • 278. #J1LBDS @JosePaumard The Collector API : partioningBy Creates a Map<Boolean, …> on a predicate map.get(TRUE) returns the list people older than 20 Map<Boolean, List<Person>> map = persons .stream() .collect( Collectors.partitioningBy(p -> p.getAge() > 20) ) ;
  • 279. #J1LBDS @JosePaumard The Collector API : partioningBy Can further process the list of persons Map<Boolean, TreeSet<String>> map = persons .stream() .collect( Collectors.partitioningBy( p -> p.getAge() > 20, Collectors.mapping( Person::getLastName, Collectors.toCollection(TreeSet::new)) ) ) ) ;
  • 280. #J1LBDS @JosePaumard The Collector API : collectingAndThen Collect data with a downstream Then apply a function called a « finisher » Useful for putting the result in a immutable collection
  • 281. #J1LBDS @JosePaumard The Collector API : collectingAndThen In this case « Map::entrySet » is a finisher Set<Map.Entry<Integer, List<Person>>> set = persons .stream() .collect( Collectors.collectingAndThen( Collectors.groupingBy( Person::getAge), // downstream, builds a map Map::entrySet // finisher, applied on the map ) ;
  • 282. #J1LBDS @JosePaumard The Collector API : collectingAndThen Map<Integer, List<Person>> map = // immutable persons .stream() .collect( Collectors.collectingAndThen( Collectors.groupingBy( Person::getAge), // the downstream builds a map Collections::unmodifiableMap // finisher is applied to the // map ) ;
  • 283. #J1LBDS @JosePaumard Some real examples https://github.com/JosePaumard/jdk8-lambda-tour
  • 285. #J1LBDS @JosePaumard Conclusion Why are lambdas introduced in Java 8 ?
  • 286. #J1LBDS @JosePaumard Conclusion Why are lambdas introduced in Java 8 ? Because it’s in the mood !
  • 288. #J1LBDS @JosePaumard Conclusion Why are lambdas introduced in Java 8 ? Because it’s in the mood !
  • 289. #J1LBDS @JosePaumard Conclusion Why are lambdas introduced in Java 8 ? Because it’s in the mood ! Because it allows to write more compact code !
  • 290. #J1LBDS @JosePaumard Compact code is better ! An example of compact code (in C) http://www.codeproject.com/Articles/2228/Obfuscating-your-Mandelbrot-code #include "stdio.h" main() { int b=0,c=0,q=60,_=q;for(float i=-20,o,O=0,l=0,j,p;j=O*O,p=l*l, (!_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,p=j=O=l=0,c++,stdout)), _=q:l=2*O*l+i/20,O=j-p+o),b=c%q,c<2400;o=-2+b*.05) ; }
  • 291. #J1LBDS @JosePaumard Compact code is better ! An example of compact code (in C) http://www.codeproject.com/Articles/2228/Obfuscating-your-Mandelbrot-code #include "stdio.h" main() { int b=0,c=0,q=60,_=q;for(float i=-20,o,O=0,l=0,j,p;j=O*O,p=l*l, (!_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,p=j=O=l=0,c++,stdout)), _=q:l=2*O*l+i/20,O=j-p+o),b=c%q,c<2400;o=-2+b*.05) ; } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++ ++ +++++++++++ +++++++++++++++++++++++++++++++++++ +++++++ ++++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++++ ++++++++ ++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++ +++++ +++++++++++++++++++++++++++++++++ ++++++ +++++++++++++++++++++++ + +++++ ++++++ +++++++++++++++++++++++ ++ ++++++ ++++++++++++++++++++++ + ++++++ ++++++++++++++++++++++ + ++++++ ++++++++++++++++++++ + + +++++++ ++++++ ++++++++ ++++++++++++++++++++ + + +++++++ ++++++++++++++++++++++ + ++++++ ++++++++++++++++++++++ + ++++++ +++++++++++++++++++++++ ++ ++++++ +++++++++++++++++++++++ + +++++ ++++++ +++++++++++++++++++++++++++++++++ ++++++ +++++++++++++++++++++++++++++++++ +++++ ++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++++ ++++++++ ++++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++++ +++++++ ++++++++++++++++++++++++++++++++++++ ++ +++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  • 292. #J1LBDS @JosePaumard Conclusion Why are lambdas introduced in Java 8 ? Because it’s in the mood ! Because it allows to write more compact code !
  • 293. #J1LBDS @JosePaumard Conclusion Why are lambdas introduced in Java 8 ? Because it brings new and efficient patterns, that enable easy and safe parallelization, -needed by modern applications -needed by API writers
  • 294. #J1LBDS @JosePaumard Conclusion Java 8 is here, it’s the biggest update in 15 years
  • 295. #J1LBDS @JosePaumard Conclusion Java 8 is here, it’s the biggest update in 15 years Moving to Java 8 means a lot of work for us developers ! -Self training -Changing our habits
  • 296. #J1LBDS @JosePaumard Conclusion Java 8 is here, it’s the biggest update in 15 years Moving to Java 8 means a lot of work for us developers ! -Self training -Changing our habits -Convincing our bosses (sigh…)
  • 297. #J1LBDS @JosePaumard Conclusion Books are there ! available available available available available
  • 298. #J1LBDS @JosePaumard Conclusion Java 8 is the biggest update in 15 years « Java is a blue collar language. It’s not PhD thesis material but a language for a job » – James Gosling, 1997
  • 299. #J1LBDS @JosePaumard Conclusion Java 8 is the biggest update in 15 years « Language features are not a goal unto themselves; language features are enablers, encouraging or discouraging certain styles and idioms » – Brian Goetz, 2013
  • 300. #J1LBDS @JosePaumard Conclusion Java 8 is the biggest update in 15 years The good news is : Java is still Java !