Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Richard Warburton
James Gough
Raoul-Gabriel Urma
Outline of module
1. Why Java 8?
2. Behaviour Parameterisation
3. What is a lambda?
4. Functional interfaces: where to use
lambdas?
5. Method references
6. Advanced details
Why Java 8?
Why Java 8? (1)
Collections.sort(inventory,new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
});
Why Java 8? (1)
Collections.sort(inventory,new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
});
VS
inventory.sort(comparing(Apple::getWeight));
Why Java 8? (2)
• In practice:
– it’s hard because you now have to figure out how
to distribute a piece of work amongst 4 people.
– It’s easier to just pass the whole piece of work to
one person.
Why Java 8? (2)
List<Apple> result =
filter(inventory, (Apple apple) -> apple.getWeight() > 150);
List<Integer> result =
filter(numbers, (Integer i) -> i % 2 == 0);
List<Apple> result =
filter(inventory, (Apple a) -> apple.getWeight() >
150);
Moral of the story
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});
Real world example: Runnable
Before:
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});
After:
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().
compareTo(a2.getWeight()));
Syntax
or
1. () -> {}
2. () -> "Raoul"
3. () -> {return "Richard";}
4. (Integer i) -> return "James" + i;
5. (String s) -> {"Raoul";}
Functional interfaces: where to use
lambdas?
Where and how to use lambdas?
Before:
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});
After:
inventory.sort(
(Apple a1, Apple a2) ->
a1.getWeight().compareTo(a2.getWeight()));
Quiz: Where to use lambdas (1)
• IntUnaryOperator, LongUnaryOperator,
DoubleUnaryOperator
• …
Functional interfaces starter kit
examples
Predicate<List<String>> p = (List<String> list) -> list.isEmpty();
Consumer<Apple> c =
(Apple a) -> System.out.println(a.getWeight());
@FunctionalInterface
public interface Predicate<T>{
public boolean test(T);
}
Exercise
com.java_8_training.problems.lambdas.LambdaRefactor
Method references
Method references
Before
After
str.sort(String::compareToIgnoreCase);
Quiz: method references
com.java_8_training.problems.lambdas.MethodRefsQuizTest
Quiz: method references (answers)
Answers:
1. Function<String, Integer> stringToInteger =
(String s) -> Integer.parseInt(s);
inventory.sort(new AppleComparator());
Anonymous class
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
Lambdas
inventory.sort(
(Apple a1, Apple a2) ->
a1.getWeight().compareTo(a2.getWeight())
);
Lambdas
inventory.sort(
(Apple a1, Apple a2) ->
a1.getWeight().compareTo(a2.getWeight())
);
Comparator<Apple> byWeight =
Comparator.comparing((Apple a) -> a.getWeight());
inventory.sort(byWeight);
Method references
Comparator<Apple> byWeight =
Comparator.comparing(Apple::getWeight);
inventory.sort(byWeight);
Tidy up
import static java.util.Comparator.comparing;
inventory.sort(comparing(Apple::getWeight));
Object o =
(Runnable) () -> {System.out.println(“Tricky example”); };
Type inference (1)
int sum = 0;
list.forEach((Integer i) -> { sum += i; });
// illegal; local variable 'sum' is not effectively final
Using local variables (2) : why the
restriction?
• Technical reason:
• each thread has its own stack, locals are stored on
stack
• what if thread A has a local and then thread B tries
to access it
• Now A de-allocates it - What’s with B?
Design decision:
• same semantics as inner classes
• mutability of locals is undesirable because it
encourages sequential patterns!
Capturing variables : hack restriction?
com.java_8_training.problems.lambdas.WrapUpTest
Summary
Java 8
int sum = 0;
for(Integer i : listOfIntegers){
sum += i;
}
Parallel Sum
• java.lang.Runnable?
• synchronized?
• Monitors?
• Message Passing?
• Work-stealing?
• Fork/Join (Java7)?
Parallel sum: Fork/Join
Exercise (1)
com.java_8_training.problems.lambdas.
BehaviourParameterisation
Exercise (2)
Towards prettyPrint...
List<String> lowCaloricDishesName =
dishes.parallelStream()
.filter(d -> d.getCalories() < 400)
stream
.sorted(comparing(Dish::getCalories))
processing
.map(Dish::getName)
.collect(toList());
Behaviour parameterisation
Behaviour parameterisation
List<String> lowCaloricDishesName =
dishes.parallelStream()
.filter(d -> d.getCalories() < 400) No shared
.sorted(comparing(Dish::getCalories)) variable
.map(Dish::getName) or object
.collect(toList());
3rd attempt: filtering with everything
public static List<Apple>
filter (List<Apple> inventory, String color, int weight,
boolean flag) {
List<Apple> result = new ArrayList<>();
for (Apple apple: inventory){
if ( (flag && apple.getColor().equals(color))
|| (!flag && apple.getWeight() > weight) ){
result.add(apple); }
}
return result;
}