5. Lambda Expressions: An example
How about sorting a list of Apples?
To sort any object in Java, we need to
understand the Comparator Interface.
6. Lambda Expressions: An example
How about sorting a list of Apples?
To sort any Object in Java, we need to
implement the Comparator Interface, which
defines logic for: How to order two objects.
7. Lambda Expressions: An example
How about sorting a list of Apples?
Comparator<Apple> byWeight = new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight().compareTo(o2.getWeight());
}
};
8. Lambda Expressions: An example
How about sorting a list of Apples?
Comparator<Apple> byWeight1 = (Apple a1, Apple a2) ->
a1.getWeight().compareTo(a2.getWeight());
10. Constructing Lambda
A lambda expression is composed of three
parts:
A list of parameters, an arrow:
(Apple a1, Apple a2) ->
11. Constructing Lambda
A lambda expression is composed of three
parts:
A list of parameters, an arrow and a body:
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
12. Valid Lambda Expressions
Here are some examples of valid lambda
expressions:
● (String anyString) -> anyString.length()
13. Valid Lambda Expressions
Here are some examples of valid lambda
expressions:
● (String anyString) -> anyString.length()
● (Apple a) -> a.getWeight() > 150
14. Valid Lambda Expressions
Here are some examples of valid lambda
expressions:
● (String anyString) -> anyString.length()
● (Apple a) -> a.getWeight() > 150
● () -> 47
15. Valid Lambda Expressions
Here are some examples of valid lambda expressions:
● (String anyString) -> anyString.length()
● (Apple a) -> a.getWeight() > 150
● () -> 47
● (int a, int b) -> {
System.out.println("Sqaure:");
System.out.println(a*b);
}
17. Functional Interfaces
A functional interface contains only a one
abstract method.
In Java 8 annotations, It is annotated as
@FunctionalInterface
18. Functional Interfaces: Examples
● Runnable is a functional interface with an
abstract method run().
● Comparator<T> is a functional interface with
an abstract method compareTo()
19. Why functional Interface
A functional interface let you describe a
lambda function. In other words,
Lambda expressions are used to instantiate a
functional interface.
@FunctionalInterface
interface Calculation {
int calculate(int a, int b);
}
20. Why functional Interface
A functional interface let you describe a lambda
function. In other words,
Lambda expressions are used to instantiate a
functional interface.
@FunctionalInterface
interface Calculation {
int calculate(int a, int b);
}
Calculation addition = (Int a, Int b) → (a+b)
21. Function Descriptor
The signature of an abstract method of a
functional interface is called function
descriptor.
@FunctionalInterface
interface Calculation {
int calculate(int a, int b);
}
22. Function Descriptor: Example
The signature of an abstract method of a
functional interface is called function
descriptor.
@FunctionalInterface
interface Calculation {
int calculate(int a, int b);
}
Calculation addition = (Int a, Int b) → (a+b)
23. Function Descriptor: Example
The signature of an abstract method of a
functional interface is called function
descriptor.
@FunctionalInterface
interface Calculation {
int calculate(int a, int b);
}
Calculation subtraction = (Int a, Int b) → (a-b)
26. Interface's default methods
An interface can declare a method and can
provide a default implementation for it.
private interface InterfaceOrTrait{
default String alreadyDone() {
return "Default implementation of method String";
}
}
27. Why Interface's default methods
● Adding enhancement to language without
hurting the backward compatibility.
28. Why Interface's default methods
● Adding enhancement to language without hurting the backward compatibility.
● Method for a default situation where any implementing class fails to implement
certain methods in the Interface e.g.
interface Iterator<T> {
boolean hasNext();
T next();
default void remove() {
throw new UnsupportedOperationException();
}
}
30. Method References
● Provides syntax to refer directly to existing
methods
● Can pass existing methods just like lambdas
to functions
● It is better to re use the existing methods
instead of creating lambda expressions for
them.
35. Why Streams
● Advantages over Collections
● No Storage
● Laziness-seeking
● Functional in nature
● No Bounds (infinite streams)
● Parallelizable
36. Streams API: An Example
Comparator<Apple> byWeight = new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight().compareTo(o2.getWeight());
}
}
37. Streams API: An Example
listOfApples.add(new Apple("green",12.0));
listOfApples.add(new Apple("red",12.0));
listOfApples.add(new Apple("green",17.0));
listOfApples.add(new Apple("yellow",12.0));
listOfApples.stream()
.filter( apple -> apple.getColor().equals("green"))
.sorted(byWeight)
.forEach(System.out::println);
38. Streams API: An Example
listOfApples.add(new Apple("green",12.0));
listOfApples.add(new Apple("red",12.0));
listOfApples.add(new Apple("green",17.0));
listOfApples.add(new Apple("yellow",12.0));
listOfApples.stream()
.filter( apple -> apple.getColor().equals("green"))
.sorted(byWeight)
.forEach(System.out::println);
39. Streams API: An Example
listOfApples.add(new Apple("green",12.0));
listOfApples.add(new Apple("red",12.0));
listOfApples.add(new Apple("green",17.0));
listOfApples.add(new Apple("yellow",12.0));
listOfApples.stream()
.filter( apple -> apple.getColor().equals("green"))
.sorted(byWeight)
.forEach(System.out::println);
40. Streams API: An Example
listOfApples.add(new Apple("green",12.0));
listOfApples.add(new Apple("red",12.0));
listOfApples.add(new Apple("green",17.0));
listOfApples.add(new Apple("yellow",12.0));
listOfApples.stream()
.filter( apple -> apple.getColor().equals("green"))
.sorted(byWeight)
.forEach(System.out::println);
41. Creating Streams
● From a Collections
List<Apple> listOfApples = new ArrayList();
listOfApples.add(new Apple("yellow",12.0));
Stream<Apple> apples = listOfApples.stream()
42. Creating Streams
● From a Collections
List<Apple> listOfApples = new ArrayList();
listOfApples.add(new Apple("yellow",12.0));
Stream<Apple> apples = listOfApples.stream()
● From Primitive values
Stream<String> wordStream = Stream.of("Value1 ", "Value2", "Value3", "Value4");
43. Creating Streams
● From a Collections
List<Apple> listOfApples = new ArrayList();
listOfApples.add(new Apple("yellow",12.0));
Stream<Apple> apples = listOfApples.stream()
● From Primitive values
Stream<String> wordStream = Stream.of("Value1 ", "Value2", "Value3", "Value4");
● From An Array
int [] primitives = {2,4,6,8,10};
Stream<String> stream = Arrays.stream(primitives);
46. Operations on Streams
● Reduction
Double totalWeight = listOfApples.stream().mapToDouble(Apple::getWeight).sum();
Double totalReducedWeight =
listOfApples.stream().mapToDouble(Apple::getWeight).reduce(0,(a,b) -> a+b);
The reduce operation in this example takes two arguments:
● identity: The identity element is both the initial value of the reduction
● accumulator: The accumulator function takes two parameters: a partial result of the reduction
and the next element of the stream
47. Operations on Streams
● Grouping
Map<String, List<Apple>> applesByColor =
listOfApples.stream().collect(Collectors.groupingBy(Apple::getColor));
The above method uses groupingBy method to join the apples by color and returns a Map of
type <String, List<Apple>
48. Operations on Streams
● Stats
DoubleSummaryStatistics weightStats =
listOfApples.stream().mapToDouble(Apple::getWeight).summaryStatistics();
System.out.println("The max of Double" + weightStats.getAverage());
System.out.println("The min of Double" + weightStats.getMin());
System.out.println("The max of Double" + weightStats.getMax());
The DoubleSummaryStatistics class contain the stats like count, max, min etc.
49. References
● Java 8 In Action:
Book by: Mario-Fusco,Alan Mycroft, Raoul-
Gabriel Urma