Free your lambdas
-
Upload
jose-paumard -
Category
Education
-
view
684 -
download
0
Transcript of Free your lambdas
@JosePaumard#FreeLambdas
Agenda
Tutorial session: we will start at the very beginning!
…and explore how to build functional interfaces to design
new APIs
This is about lambdas and functional interfaces
So not much about Streams & Collectors
@JosePaumard#FreeLambdas
Agenda
Other sessions:
TUT6198: Henri Tremblay, Mon 19 8h30-10h30
TUT 4041: Maurice Naftalin, Tue 20 8h30-10h30
CON5544: Collectors Fair, Tue 20 11h-12h Cont B 1/2/3
HOL3288: Lab on lambdas Wed 21 10h-12h
@JosePaumard#FreeLambdas
A first example
What is this code doing?
Comparator<Person> cmp = new Comparator<Person>() {
@Overridepublic int compare(Person p1, Person p2) {
return p1.getLastName().compareTo(p2.getLastName());}
};
@JosePaumard#FreeLambdas
A first example
What is this code doing?
Comparator<Person> cmp = new Comparator<Person>() {
@Overridepublic int compare(Person p1, Person p2) {
int cmp = p1.getLastName().compareTo(p2.getLastName());if (cmp == 0) {
return p1.getFirstName().compareTo(p2.getFirstName());} else {
return cmp;}
}};
@JosePaumard#FreeLambdas
A first example
What is this code doing?Comparator<Person> cmp = new Comparator<Person>() {
@Overridepublic int compare(Person p1, Person p2) {
int cmp = p1.getLastName().compareTo(p2.getLastName());if (cmp == 0) {
cmp = p1.getLastName().compareTo(p2.getFirstName());if (cmp == 0) {
return p1.getAge() - p2.getAge();} else {
return cmp;}
} else {return cmp;
}}
};
@JosePaumard#FreeLambdas
A first example
What is this code doing?Comparator<Person> cmp = new Comparator<Person>() {
@Overridepublic int compare(Person p1, Person p2) {
int cmp = p1.getLastName().compareTo(p2.getLastName());if (cmp == 0) {
cmp = p1.getFirstName().compareTo(p2.getFirstName());if (cmp == 0) {
return p1.getAge() - p2.getAge();} else {
return cmp;}
} else {return cmp;
}}
};
@JosePaumard#FreeLambdas
A first example
What is this code doing?
Comparator<Person> cmp = Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName).thenComparing(Person::getAge);
@JosePaumard#FreeLambdas
A closer look at the Comparator
Suppose we want to sort strings of characters
1) We create a comparator:
Comparator<String> comparator = new Comparator<String>() {public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());}
};
@JosePaumard#FreeLambdas
A closer look at the Comparator
Suppose we want to sort strings of characters
1) We create a comparator:
2) We pass it to the right method:
Comparator<String> comparator = new Comparator<String>() {public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());}
};
Arrays.sort(strings, comparator); Collections.sort(list, comparator) ;
@JosePaumard#FreeLambdas
A closer look at the Comparator
What did we do?
We passed a piece of code as a parameter to a method
And this method will use this code later
@JosePaumard#FreeLambdas
A closer look at the Comparator
Why did we use an instance of an anoymous class?
@JosePaumard#FreeLambdas
A closer look at the Comparator
Why did we use an instance of an anoymous class?
Because there is no other way in Java 7!
@JosePaumard#FreeLambdas
Another way of writing it
Our comparator:Comparator<String> comparator = new Comparator<String>() {
public int compareTo(String s1, String s2) {
return Integer.compare(s1.length(), s2.length()) ;
}
}
@JosePaumard#FreeLambdas
Another way of writing it
Our comparator:
Becomes:
Comparator<String> comparator = new Comparator<String>() {
public int compareTo(String s1, String s2) {
return Integer.compare(s1.length(), s2.length()) ;
}
}
Comparator<String> comparator =
(String s1, String s2) ->
Integer.compare(s1.length(), s2.length()) ;
@JosePaumard#FreeLambdas
Back to the Comparator interface
The Comparator interface…
public interface Comparator<T> {
public int compare(T t1, T t2) ;}
@JosePaumard#FreeLambdas
Back to the Comparator interface
The Comparator interface…
becomes a functional interface in Java 8
public interface Comparator<T> {
public int compare(T t1, T t2) ;}
@JosePaumard#FreeLambdas
Back to the Comparator interface
The Comparator interface…
becomes a functional interface in Java 8
because it has a single abstract method
public interface Comparator<T> {
public int compare(T t1, T t2) ;}
@JosePaumard#FreeLambdas
Back to the Comparator interface
A functional interface can be annotated
But it is optional
@FunctionalInterfacepublic interface Comparator<T> {
public int compare(T t1, T t2) ;}
@JosePaumard#FreeLambdas
So…
Writing a lambda is a matter of finding what interface to
implement
The type of a lambda is always known at compile time
The method is always the same:
- copy / paste the block of parameters
- little ASCII art arrow
- implement the method
@JosePaumard#FreeLambdas
A weird thing…
We wrote this code:
The forEach() method is defined on the Iterable interface
List<String> strings = ...;
strings.forEach(
System.out::println // method reference (bound instance)
) ;
@JosePaumard#FreeLambdas
A weird thing…
We wrote this code:
The forEach() method is defined on the Iterable interface
Do we really want to refactor all the Collection API?
List<String> strings = ...;
strings.forEach(
System.out::println // method reference (bound instance)
) ;
@JosePaumard#FreeLambdas
Default methods
Breaking the backward compatibility is not possible in Java
The way interfaces work has been modified:
public interface Iterable<E> {
// usual methods
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}
@JosePaumard#FreeLambdas
Default methods
We can now add methods in interfaces with their
implementation
Those are « normal » methods
It is a new concept of interface, not a new concept of
method
@JosePaumard#FreeLambdas
Default & static methods
We can now add methods in interfaces with their
implementation
Those are « normal » methods
It is a new concept of interface, not a new concept of
method
And static methods are allowed too!
@JosePaumard#FreeLambdas
Back to the functional interface
A functional interface is an interface
with only one abstract method
So default & static methods do not count
@JosePaumard#FreeLambdas
So…
Interfaces in Java 8:
- Functional interfaces to write lambda expressions
- Default methods, can be used to compose them
- Static methods, can be used as factory
We better readability, better robustness…
and better performances!
(Youtube: Lambda a peek under the hood by B. Goetz)
@JosePaumard#FreeLambdas
Package java.util.function
4 categories of functional interfaces:
ConsumerSupplierFunctionPredicate
@JosePaumard#FreeLambdas
Package java.util.function
4 categories of functional interfaces:
Consumer t -> {};Supplier () -> t;Function t -> u;Predicate t -> true;
@JosePaumard#FreeLambdas
Package java.util.function
4 categories of functional interfaces:
Consumer t -> {}; s -> System.out.println(s);Supplier () -> t; () -> new Ballon();Function t -> u; person -> person.getAge();Predicate t -> true; age -> age > 20;
@JosePaumard#FreeLambdas
Package java.util.function
4 categories of functional interfaces:
Runnable () -> {};Consumer t -> {}; s -> System.out.println(s);Supplier () -> t; () -> new Ballon();Function t -> u; person -> person.getAge();Predicate t -> true; age -> age > 20;
@JosePaumard#FreeLambdas
Package java.util.function
4 categories of functional interfaces:
Runnable () -> {}; () -> logger.log(message);Consumer t -> {}; s -> System.out.println(s);Supplier () -> t; () -> new Ballon();Function t -> u; person -> person.getAge();Predicate t -> true; age -> age > 20;
@JosePaumard#FreeLambdas
Back to the Comparator
Let us write a comparator of people
- Using an anonymous class
- Then a lambda
@JosePaumard#FreeLambdas
Method reference
There are 4 types of method references
Nom Syntaxe
Static RefType::staticMethod
Bound instance expr::instMethod
Unbound instance RefType::instMethod
Constructor ClassName::new
@JosePaumard#FreeLambdas
Method reference
There are 4 types of method references
Lambda Method Reference
d -> Math.sin(d) Math::sin
s -> System.out.println(s) System.out::println
(s, t) -> s.compareTo(t) String::compareTo
name -> new Person(name) Person::new
@JosePaumard#FreeLambdas
What about patterns?
Let us talk about the GoF
The factory pattern
The registry & builder patterns
@JosePaumard#FreeLambdas
Conclusion
Lambdas are not just a nice way of writing instances of
anonymous classes
Functional interfaces + default methods + factory methods
provide new ways of implementing well-known patterns for
our applications & APIs