SlideShare a Scribd company logo
JAVA 8 - BY EXAMPLE!
PATTERNS AND PRACTICES FOR LAMBDAS, STREAMS,
OPTIONAL...
Createdby /MarkHarrison @markglh
INTERFACE DEFAULT METHODS
Interfaces can now have default & static methods!
Allows new interface methods to be added without breaking
existing implementations
Multiple inheritance!
public interface Comparator<T> {
default Comparator<T> reversed() {
// Implementation here
}
public static Comparator<T> naturalOrder() {
// Implementation here
}
}
MULTIPLE INHERITANCE...
What if a class inherits the same default method from two
interfaces???
1.Class methods always win. Whether it’s this class or the
superclass, it will take priority
2.If multiple interfaces de ne the same method with a
default implementation, then the most speci c is selected
(the child in inheritance terms)
3.If it’s not obvious then the compiler will cry, we need to
explicitly choose: INTERFACE.super.METHODNAME
LAMBDAS YOU SAY?
Basically just a shorthand method implementation
Concise and much improved replacement for Anonymous
inner classes
Makes it easy to pass behaviour around
Pass the behaviour into the method, ips the design on its
head
Lexically scoped (this is effectively shared with the
surrounding method)
SYNTAX PLEASE!
(int x, int y) -> x + y
Argument types can be inferred by the compiler:
(x, y) -> x + y
Zero-arg Lambdas are also possible:
() -> "Java 8!"
But how can we use them?
Consumer<String> inferredConsumer =
x -> System.out.println(x);
WAT?!?
FUNCTIONAL INTERFACES
A Functional Interface is any interface with one Single
Abstract Method
The parameters that the Lambda accepts and returns must
match the interface (including exceptions)
@FunctionalInterface annotation is provided to
highlight these interfaces, it is just a marker though, any SAM
interface will work - the annotation simply enforces this at
compile time
So... When we pass or assign a Lambda:
1. First the Lambda is converted into a Functional Interface
2. Secondly it is invoked via this generated implementation
LAMBDA EXAMPLE 1 - PREDICATES
Have you ever written code like this?
@FunctionalInterface //Added in Java8
public interface Predicate<T> {
boolean test(T t);
}
private void printMatchingPeople(
List<Person> people,
Predicate<Person> predicate) {
for (Person person : people) {
if (predicate.test(person)) {
System.out.println(person);
}
}
}
LAMBDA EXAMPLE 1 - PREDICATES
Pre Java 8:
public class PersonOver50Predicate
implements Predicate<Person> {
public boolean test(Person person) {
return person.getAge() > 50;
}
}
printMatchingPeople(loadsOfPeople,
new PersonOver50Predicate());
LAMBDA EXAMPLE 1 - PREDICATES
Java 8:
printMatchingPeople(loadsOfPeople,
x -> x.getAge() > 50);
Notice the signature matches that of the Predicate, the compiler
automatically gures out the rest
What if we had an existing Predicate we wanted to enhance?
Composite Predicates FTW... :-)
Predicate<Person> ageCheck = x -> x.getAge() > 50;
printMatchingPeople(loadsOfPeople,
ageCheck.and(x -> x.getIq() > 100));
LAMBDA EXAMPLE 2 - RUNNABLE
Pre Java 8 mess:
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Meh!");
}
};
r1.run();
Java 8:
Runnable r = () -> System.out.println("Woop!");
r.run();
LAMBDA EXAMPLE 3 - COLLECTIONS
Lambdas make lots of new Collection methods possible...
List<String> strings = new ArrayList<>();
Collections.addAll(strings, "Java", "7", "FTW");
Do something on every element in the List
strings.forEach(x -> System.out.print(x + " "));
//Prints: "Java 7 FTW"
LAMBDA EXAMPLE 4 - MORE COLLECTIONS
Replace every matching element in the List
strings.replaceAll(x -> x == "7" ? "8" : x);
strings.forEach(x -> System.out.print(x + " "));
//Prints: "Java 8 FTW"
Remove matching elements from the List
strings.removeIf(x -> x == "8");
strings.forEach(x -> System.out.print(x + " "));
//Prints: Java FTW
LAMBDA EXAMPLE 5 - COMPARATORS
@FunctionalInterface //Added in Java8 version
public interface Comparator<T> {
int compare(T o1, T o2);
//Java 8 adds loads of default methods
}
LAMBDA EXAMPLE 6 - COMPARATORS 2
List<Person> loadsOfPeople = ...;
Pre Java 8:
public class SortByPersonAge
implements Comparator<Person> {
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
}
Collections.sort(loadsOfPeople,
new SortByPersonAge());
Java 8:
Collections.sort(loadsOfPeople,
(p1, p2) -> p1.getAge() - p2.getAge());
LAMBDA EXAMPLE 7 - COMPARATORS 3
As usual in Java 8... the Comparator interface provides plenty
of useful default & static methods...
//"comparing" static method simplifies creation
Comparator<Person> newComparator =
Comparator.comparing(e -> e.getIq());
//"thenComparing" combines comparators
Collections.sort(loadsOfPeople,
newComparator.thenComparing(
Comparator.comparing(e -> e.getAge())));
LAMBDA EXAMPLE 8 - COMPARATORS 4
and more...
//More useful Collection methods...
loadsOfPeople4.sort(
Comparator.comparing(e -> e.getIq()));
//And finally... Method references
loadsOfPeople.sort(
Comparator.comparing(Person::getAge));
INTRODUCING METHOD REFERENCES
Any method can be automatically “lifted” into a function. It
must simply meet contract of the FunctionalInterface
Can be easier to debug & test than Lambdas, more descriptive
stack traces
Promotes re-use, keeping code DRY
Uses the "::" syntax
METHOD REFERENCES TYPES
Reference to... Example
a static method Class::staticMethodName
an instance method of
a speci c object
object::instanceMethodName
an instance method of
an arbitrary object
Class::methodName
a constructor ClassName::new
REFERENCE TO A STATIC METHOD
A simple reference to a static method
//isPersonOver50 is a static method
printMatchingPeople(loadsOfPeople,
PersonPredicates::isPersonOver50);
This is equivalent to
printMatchingPeople(loadsOfPeople,
x -> x.getAge() > 50);
REFERENCE TO AN INSTANCE METHOD OF A
SPECIFIC OBJECT
A reference to a method on an object instance
List<String> strings = ...
//print is a method on the "out" PrintStream object
strings.forEach(System.out::print);
This is equivalent to
strings.forEach(x -> System.out.print(x));
REFERENCE TO AN INSTANCE METHOD OF AN
ARBITRARY OBJECT
Examine this simpli ed de nition of a map function
public interface Function<T,R> {
public R apply(T t);
}
public <T, R> List<R> map(Function<T, R> function,
List<T> source) {
/* applies the function to each element,
converting it from T to R */
}
REFERENCE TO AN INSTANCE METHOD OF AN
ARBITRARY OBJECT CONT...
Although it looks like we're referencing a Class method, we're
invoking an instance method on the object(s) passed in the call
List<Person> loadsOfPeople = ...
List<Integer> namesOfPeople =
map(Person::getAge, loadsOfPeople);
This is equivalent to
map(person -> person.getAge(), loadsOfPeople);
REFERENCE TO A CONSTRUCTOR
Uses the constructor to create new objects, the constructor
signature must match that of the @FunctionalInterface
List<String> digits = Arrays.asList("1", "2", "3");
//Transforms a String into a new Integer
List<Integer> numbers = map(Integer::new, digits);
This is equivalent to
map(s -> new Integer(s), digits);
WHAT'S WRONG WITH COLLECTIONS
Every application uses Collections, however Collections are
dif cult to query and aggregate, requiring several levels of
iteration and conditionals, basically it’s messy and painful
Writing multi-threaded code to do this manually is dif cult to
write and maintain
Imagine writing this manually
Stream<String> words=Stream.of("Java", "8", "FTW");
Map<String, Long> letterToNumberOfOccurrences =
words.map(w -> w.split(""))
.flatMap(Arrays::stream)
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()));
//Prints: //{a=2, T=1, F=1, v=1, W=1, 8=1, J=1}
INTRODUCING STREAMS!
A Stream is a conceptually xed data structure in which
elements are computed on demand
Streams iterate internally, you don’t have to worry about
handling the iteration
Pipelining: Akin to the “pipe” command in unix, allowing
aggregations to be chained together
Automatic optimisation: short-circuiting and lazy processing
Can be in nite
Can be executed in parallel automatically using
parallelStream or parallel()
MORE STREAMS...
Can be created from multiple sources:
Arrays.stream(...), Stream.of(1, 2, 3, 4),
Stream.iterate(...), Stream.range(...),
Random.ints(), Files.lines(...)...
Two types of operations:
Intermediate (aggregation): lter, map, atMap, sorted ...
Terminal: collect, reduce, forEach, ndAny ...
Specialised Streams:
IntStream, LongStream and DoubleStream: better
performance for those unboxed types
MAP
public <R> Stream<R> map(Function<T, R> mapper);
The mapper Function converts each element from T to R. The
result is then added, as is, to the Stream
FLATMAP
public <R> Stream<R> flatMap(Function<T,
Stream<R>> mapper);
The mapper Function converts each element from T to a
Stream of R
This is the key difference to map, the function itself returns a
Stream rather than one element
This Stream is then attened (merged) into the main Stream
To put it another way: atMap lets you replace each value of a
Stream with another Stream, and then it concatenates all the
generated streams into one single stream
REDUCE
public T reduce(T identity,
BinaryOperator<T> accumulator);
public Optional<T> reduce(
BinaryOperator<T> accumulator);
//This is the function contained in BinaryOperator
R apply(T t, U u);
Terminal Operation
Takes a Stream of values and repeatedly applies the
accumulator to reduce them into a single value
The accumulator is passed the total so far (T) and the current
element (U)
If passed, identity provides the initial value, rather than the
rst element
REDUCE CONTINUED...
int totalAgeUsingReduce = loadsOfPeople.stream()
.map(Person::getAge) //contains 5, 10, 15
.reduce(0, (total, current) -> total + current);
1.First we map the Person to the age int
2.reduce then starts at 0, and adds the current element, 5
3.reduce continues by adding the current total 5, to the next
element, 10
4. nally reduce adds the current total 15, to the next element
15
5.Tada, we've added up all the ages: 30!
COLLECTORS
The collect method is a terminal operation which takes various
"recipes", called Collectors for accumulating the elements of
a stream into a summary result, or converting to a speci c type
(such as a List)
List<String> listOfStrings = loadsOfPeople.stream()
.map(x -> x.getName())
.collect(Collectors.toList());
The argument passed to collect is an object of type java
.util.stream.Collector
It describes how to accumulate the elements of a stream into
a nal result
Can be used for Grouping, Partitioning, Averaging, ...
STREAMS EXAMPLE 1
List<Integer> numbers = Arrays.asList(1, 2 ... 8);
List<Integer> twoEvenSquares = numbers.stream()
.filter(n -> n % 2 == 0) //Filter odd numbers
.map(n -> n * n) ////Multiply by itself
.limit(2)//Limit to two results
.collect(Collectors.toList()); //Finish!
Imagine a println in each step...
filtering 1
filtering 2
mapping 2
filtering 3
filtering 4
mapping 4
twoEvenSquares = List[4, 16]
STREAMS EXAMPLE 2
List<String> youngerPeopleSortedByIq =
loadsOfPeople.stream()
.filter(x -> x.getAge() < 50)
.sorted(Comparator
.comparing(Person::getIq).reversed())
.map(Person::getName)
.collect(Collectors.toList());
1. Filter out all people older than 50
2. Inverse sort the remaining people by IQ
3. map each person to their name (convert to a Stream<String>)
4. Convert the result to a List
STREAMS EXAMPLE 3 - SUM
int combinedAge =
loadsOfPeople.stream()
.mapToInt(Person::getAge) //returns IntStream
.sum(); //this HAS to be a specialised Stream
1. map each person to their age, producing an IntStream
2. sum the results, also supports average
STREAMS EXAMPLE 4 - MAP, REDUCE
String xml =
"<people>" +
loadsOfPeople.stream()
.map(x -> "<person>"+ x.getName() +"</person>")
.reduce("", String::concat) //start with ""
+ "</people>";
map each Person to an XML element
(<person>Steve</person>), then use String.concat to reduce
the Stream into one XML String
<people>
<person>Dave</person>
<person>Helen</person>
<person>Laura</person>
<person>Ben</person>
</people>
STREAMS EXAMPLE 5 - MAP
List<Stream<Person>> clonedPeople =
loadsOfPeople.stream()
.map(person -> Stream.of(person, person.dolly()))
.collect(Collectors.toList());
1.map creates a new Stream containing two people
2.This Stream is then added to the main Stream as-is, leaving
us with a pretty useless: List<Stream<Person>>
STREAMS EXAMPLE 6 - FLATMAP
List<Person> clonedPeople2 = loadsOfPeople.stream()
.flatMap(person -> Stream.of(person,
person.dolly()))
.collect(Collectors.toList());
1. atMap combines each element from the new Streams into
one Stream<Person>
2.So now we've got what we wanted in the rst place, a
List<Person>
Sweeet!
STREAMS EXAMPLE 7 - REDUCE
int totalAgeUsingReduce = loadsOfPeople.stream()
.map(Person::getAge)
.reduce((total, current) -> total + current)
.get(); //get the result from the Optional
This is the same as the previous example, the difference being
we don't specify a default value for reduce
Not specifying a default value means the result is Optional...
if the Stream is empty then so is the result!
STREAMS EXAMPLE 8 - GROUPING
Map<Integer, List<Person>> peopleGroupedByAge =
loadsOfPeople.stream()
.filter(x -> x.getIq() > 110)
.collect(Collectors.groupingBy(Person::getAge));
The collect method groups the ltered results by age,
producing a Map<age, <Person>>
{52=[Person{... age=52, iq=113, gender=MALE}],
60=[Person{... age=60, iq=120, gender=FEMALE}],
28=[Person{... age=28, iq=190, gender=MALE}]}
STREAMS EXAMPLE 9 - PARTITIONING
Map<Boolean, List<Person>> peoplePartitionedByAge =
loadsOfPeople.stream().filter(x -> x.getIq() > 110)
.collect(Collectors
.partitioningBy(x -> x.getAge() > 55));
The collect method partitions the ltered results by age
The Map will have two entries, true and false, according to the
Predicate
{false=[Person{... age=28, iq=190, gender=MALE}],
true=[Person{... age=60, iq=120, gender=FEMALE}]}
STREAMS EXAMPLE 10 - MULTIPLE GROUPS
Map<Integer, Double> peopleGroupedBySexAndAvgAge =
loadsOfPeople.stream()
.filter(x -> x.getIq() > 110)
.collect(
Collectors.groupingBy(Person::getAge,
Collectors.averagingInt(Person::getIq)));
We can group by multiple Collectors
Here we group by age and the average IQ of that group
{52=113.0, 60=117.5, 28=190.0}
STREAMS EXAMPLE 11 - FINDANY
loadsOfPeople.stream()
.filter(t -> t.getGender() == Person.Sex.FEMALE)
.findAny()
.ifPresent(System.out::println);
findAny either returns an element or nothing, hence we get
an Optional
ifPresent executes the Lambda if we get a result
STREAMS EXAMPLE 12 - PARALLEL
Lets iterate over 10,000,000 elements!
x -> Stream.iterate(1L, i -> i + 1)
.limit(x)
.reduce(Long::sum).get();
Executes in 80ms - we incur a penalty here because the long is
repeatedly boxed and unboxed
Executes in 211ms?! It turns out parallel isn't always a free win!
x -> Stream.iterate(1L, i -> i + 1)
.parallel().limit(x)
.reduce(Long::sum).get();
STREAMS EXAMPLE 13 - PARALLEL WIN!
x -> LongStream.rangeClosed(1L, x)
.reduce(Long::sum).getAsLong();
Executes in 24ms - much better using an unboxed Stream
Executes in 7ms - now that the Stream isn't dynamic, parallel
works much better!
x -> LongStream.rangeClosed(1L, x)
.parallel()
.reduce(Long::sum).getAsLong();
OPTIONAL
Use Optional instead of passing null around, helps prevent
NullPointerExceptions
Optional is a container that’s either empty or present, in
which case it contains a value
So anytime that you’re thinking of return or accepting a null
value in a method, use Optional instead!
public class Computer {
private Optional<Mainboard> mainboard;
}
public class Mainboard {
private Optional<Cpu> cpu;
}
public class Cpu {
private String type;
}
USING OPTIONAL
Several ways to create an Optional:
Optional.of(cpu); //Throws an NPE if cpu is null
Optional.ofNullable(cpu); //empty if cpu is null
Getting the contents from the Optional:
cpu.get(); //get CPU or throw NoSuchElementException
cpu.orElse(new Cpu()); //safe get, provides default
And more...
cpu.isPresent(); //true if present, false if empty
cpu.ifPresent(x -> System.out.println(x.getType()));
Also supports map, atMap and lter!
OPTIONAL EXAMPLE 1 - BASICS
if (mainboard.isPresent() &&
mainboard.get().getCpu().isPresent()) {
mainboard.get().getCpu().get().getType();
}
Eww! Lets try something else!
***Fails to compile, calling getType on an Optional... if only
we could atten it???
Optional<String> cpuType =
mainboard.map(Mainboard::getCpu)
.map(Cpu::getType); //Optional<Optional<Cpu>>
OPTIONAL EXAMPLE 2 - FLATMAP
Optional<String> stringOptional = mainboard
.flatMap(Mainboard::getCpu)
.map(Cpu::getType);
Lets take this further and safely get cpu type of a Computer!
Computer computer = new Computer(mainboard);
String cpu = computer.getMainboard()
.flatMap(Mainboard::getCpu)
.map(Cpu::getType)
.filter(x -> "Intel".equals(x))
.orElse("Nothing we're interested in!");
IT'S BEEN EMOTIONAL...
Slides at
Source at
Follow me
markglh.github.io/Java8Madlab-Slides
github.com/markglh/Java8Madlab-Examples
@markglh
RECOMMENDED READING
Lambdas Part 1 (Ted Neward)
Lambdas Part 2 (Ted Neward)
Lambda Expressions vs Method References (Edwin Dalorzo)
Youtube: Java 8 - more readable and exible code (Raoul-
Gabriel Urma)
Youtube: Lambda Expressions & Streams (Adib Saikali)
Java 8 Streams Part 1 (Raoul-Gabriel Urma)
Java 8 Streams Part 2 (Raoul-Gabriel Urma)
Optional - No more NPE's (Raoul-Gabriel Urma)

More Related Content

What's hot

Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
Knoldus Inc.
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - Introduction
Łukasz Biały
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
NexThoughts Technologies
 
Functional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhFunctional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singh
Harmeet Singh(Taara)
 
Java 8 Streams And Common Operations By Harmeet Singh(Taara)
Java 8 Streams And Common Operations By Harmeet Singh(Taara)Java 8 Streams And Common Operations By Harmeet Singh(Taara)
Java 8 Streams And Common Operations By Harmeet Singh(Taara)
Harmeet Singh(Taara)
 
Java8
Java8Java8
java 8 new features
java 8 new features java 8 new features
java 8 new features
Rohit Verma
 
Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
Jim Bethancourt
 
10 Sets of Best Practices for Java 8
10 Sets of Best Practices for Java 810 Sets of Best Practices for Java 8
10 Sets of Best Practices for Java 8
Garth Gilmour
 
Java 8 ​and ​Best Practices
Java 8 ​and ​Best PracticesJava 8 ​and ​Best Practices
Java 8 ​and ​Best Practices
Buddhini Seneviratne
 
Lambda Expressions in Java
Lambda Expressions in JavaLambda Expressions in Java
Lambda Expressions in Java
Erhan Bagdemir
 
Java SE 8 library design
Java SE 8 library designJava SE 8 library design
Java SE 8 library design
Stephen Colebourne
 
Java 8 new features
Java 8 new featuresJava 8 new features
Java 8 new features
Aniket Thakur
 
Functional programming principles and Java 8
Functional programming principles and Java 8Functional programming principles and Java 8
Functional programming principles and Java 8
Dragos Balan
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
Manav Prasad
 
Lambda Expressions in Java 8
Lambda Expressions in Java 8Lambda Expressions in Java 8
Lambda Expressions in Java 8
icarter09
 
Actors model in gpars
Actors model in gparsActors model in gpars
Actors model in gpars
NexThoughts Technologies
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
Andrea Iacono
 
Java 8 Features
Java 8 FeaturesJava 8 Features
Java 8 Features
Leninkumar Koppoju
 
Programming with Lambda Expressions in Java
Programming with Lambda Expressions in Java Programming with Lambda Expressions in Java
Programming with Lambda Expressions in Java
langer4711
 

What's hot (20)

Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - Introduction
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Functional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhFunctional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singh
 
Java 8 Streams And Common Operations By Harmeet Singh(Taara)
Java 8 Streams And Common Operations By Harmeet Singh(Taara)Java 8 Streams And Common Operations By Harmeet Singh(Taara)
Java 8 Streams And Common Operations By Harmeet Singh(Taara)
 
Java8
Java8Java8
Java8
 
java 8 new features
java 8 new features java 8 new features
java 8 new features
 
Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
 
10 Sets of Best Practices for Java 8
10 Sets of Best Practices for Java 810 Sets of Best Practices for Java 8
10 Sets of Best Practices for Java 8
 
Java 8 ​and ​Best Practices
Java 8 ​and ​Best PracticesJava 8 ​and ​Best Practices
Java 8 ​and ​Best Practices
 
Lambda Expressions in Java
Lambda Expressions in JavaLambda Expressions in Java
Lambda Expressions in Java
 
Java SE 8 library design
Java SE 8 library designJava SE 8 library design
Java SE 8 library design
 
Java 8 new features
Java 8 new featuresJava 8 new features
Java 8 new features
 
Functional programming principles and Java 8
Functional programming principles and Java 8Functional programming principles and Java 8
Functional programming principles and Java 8
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
Lambda Expressions in Java 8
Lambda Expressions in Java 8Lambda Expressions in Java 8
Lambda Expressions in Java 8
 
Actors model in gpars
Actors model in gparsActors model in gpars
Actors model in gpars
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
 
Java 8 Features
Java 8 FeaturesJava 8 Features
Java 8 Features
 
Programming with Lambda Expressions in Java
Programming with Lambda Expressions in Java Programming with Lambda Expressions in Java
Programming with Lambda Expressions in Java
 

Similar to Java 8 by example!

Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
Mario Fusco
 
Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional Interfaces
Ganesh Samarthyam
 
Java8
Java8Java8
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
Akaks
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
Jaanus Pöial
 
Java 8 - An Overview
Java 8 - An OverviewJava 8 - An Overview
Java 8 - An Overview
Indrajit Das
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually use
Sharon Rozinsky
 
FUNctional Programming in Java 8
FUNctional Programming in Java 8FUNctional Programming in Java 8
FUNctional Programming in Java 8
Richard Walker
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
José Paumard
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
Tomasz Kowalczewski
 
Java 8 Intro - Core Features
Java 8 Intro - Core FeaturesJava 8 Intro - Core Features
Java 8 Intro - Core Features
GlobalLogic Ukraine
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
Ganesh Samarthyam
 
java150929145120-lva1-app6892 (2).pptx
java150929145120-lva1-app6892 (2).pptxjava150929145120-lva1-app6892 (2).pptx
java150929145120-lva1-app6892 (2).pptx
BruceLee275640
 
A Brief Conceptual Introduction to Functional Java 8 and its API
A Brief Conceptual Introduction to Functional Java 8 and its APIA Brief Conceptual Introduction to Functional Java 8 and its API
A Brief Conceptual Introduction to Functional Java 8 and its API
Jörn Guy Süß JGS
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
José Paumard
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
Urs Peter
 
Java 8
Java 8Java 8
Java 8
vilniusjug
 
Java8: what's new and what's hot
Java8: what's new and what's hotJava8: what's new and what's hot
Java8: what's new and what's hot
Sergii Maliarov
 
Functional Programming
Functional ProgrammingFunctional Programming
Functional Programming
Olexandra Dmytrenko
 

Similar to Java 8 by example! (20)

Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional Interfaces
 
Java8
Java8Java8
Java8
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 
Java 8 - An Overview
Java 8 - An OverviewJava 8 - An Overview
Java 8 - An Overview
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually use
 
FUNctional Programming in Java 8
FUNctional Programming in Java 8FUNctional Programming in Java 8
FUNctional Programming in Java 8
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
Java 8 Intro - Core Features
Java 8 Intro - Core FeaturesJava 8 Intro - Core Features
Java 8 Intro - Core Features
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
 
java150929145120-lva1-app6892 (2).pptx
java150929145120-lva1-app6892 (2).pptxjava150929145120-lva1-app6892 (2).pptx
java150929145120-lva1-app6892 (2).pptx
 
A Brief Conceptual Introduction to Functional Java 8 and its API
A Brief Conceptual Introduction to Functional Java 8 and its APIA Brief Conceptual Introduction to Functional Java 8 and its API
A Brief Conceptual Introduction to Functional Java 8 and its API
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
 
Java 8
Java 8Java 8
Java 8
 
Java8: what's new and what's hot
Java8: what's new and what's hotJava8: what's new and what's hot
Java8: what's new and what's hot
 
Functional Programming
Functional ProgrammingFunctional Programming
Functional Programming
 

Recently uploaded

原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
rodomar2
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
Peter Muessig
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 

Recently uploaded (20)

原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 

Java 8 by example!

  • 1. JAVA 8 - BY EXAMPLE! PATTERNS AND PRACTICES FOR LAMBDAS, STREAMS, OPTIONAL... Createdby /MarkHarrison @markglh
  • 2. INTERFACE DEFAULT METHODS Interfaces can now have default & static methods! Allows new interface methods to be added without breaking existing implementations Multiple inheritance! public interface Comparator<T> { default Comparator<T> reversed() { // Implementation here } public static Comparator<T> naturalOrder() { // Implementation here } }
  • 3. MULTIPLE INHERITANCE... What if a class inherits the same default method from two interfaces??? 1.Class methods always win. Whether it’s this class or the superclass, it will take priority 2.If multiple interfaces de ne the same method with a default implementation, then the most speci c is selected (the child in inheritance terms) 3.If it’s not obvious then the compiler will cry, we need to explicitly choose: INTERFACE.super.METHODNAME
  • 4. LAMBDAS YOU SAY? Basically just a shorthand method implementation Concise and much improved replacement for Anonymous inner classes Makes it easy to pass behaviour around Pass the behaviour into the method, ips the design on its head Lexically scoped (this is effectively shared with the surrounding method)
  • 5. SYNTAX PLEASE! (int x, int y) -> x + y Argument types can be inferred by the compiler: (x, y) -> x + y Zero-arg Lambdas are also possible: () -> "Java 8!" But how can we use them? Consumer<String> inferredConsumer = x -> System.out.println(x);
  • 7. FUNCTIONAL INTERFACES A Functional Interface is any interface with one Single Abstract Method The parameters that the Lambda accepts and returns must match the interface (including exceptions) @FunctionalInterface annotation is provided to highlight these interfaces, it is just a marker though, any SAM interface will work - the annotation simply enforces this at compile time So... When we pass or assign a Lambda: 1. First the Lambda is converted into a Functional Interface 2. Secondly it is invoked via this generated implementation
  • 8. LAMBDA EXAMPLE 1 - PREDICATES Have you ever written code like this? @FunctionalInterface //Added in Java8 public interface Predicate<T> { boolean test(T t); } private void printMatchingPeople( List<Person> people, Predicate<Person> predicate) { for (Person person : people) { if (predicate.test(person)) { System.out.println(person); } } }
  • 9. LAMBDA EXAMPLE 1 - PREDICATES Pre Java 8: public class PersonOver50Predicate implements Predicate<Person> { public boolean test(Person person) { return person.getAge() > 50; } } printMatchingPeople(loadsOfPeople, new PersonOver50Predicate());
  • 10. LAMBDA EXAMPLE 1 - PREDICATES Java 8: printMatchingPeople(loadsOfPeople, x -> x.getAge() > 50); Notice the signature matches that of the Predicate, the compiler automatically gures out the rest What if we had an existing Predicate we wanted to enhance? Composite Predicates FTW... :-) Predicate<Person> ageCheck = x -> x.getAge() > 50; printMatchingPeople(loadsOfPeople, ageCheck.and(x -> x.getIq() > 100));
  • 11. LAMBDA EXAMPLE 2 - RUNNABLE Pre Java 8 mess: Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Meh!"); } }; r1.run(); Java 8: Runnable r = () -> System.out.println("Woop!"); r.run();
  • 12. LAMBDA EXAMPLE 3 - COLLECTIONS Lambdas make lots of new Collection methods possible... List<String> strings = new ArrayList<>(); Collections.addAll(strings, "Java", "7", "FTW"); Do something on every element in the List strings.forEach(x -> System.out.print(x + " ")); //Prints: "Java 7 FTW"
  • 13. LAMBDA EXAMPLE 4 - MORE COLLECTIONS Replace every matching element in the List strings.replaceAll(x -> x == "7" ? "8" : x); strings.forEach(x -> System.out.print(x + " ")); //Prints: "Java 8 FTW" Remove matching elements from the List strings.removeIf(x -> x == "8"); strings.forEach(x -> System.out.print(x + " ")); //Prints: Java FTW
  • 14. LAMBDA EXAMPLE 5 - COMPARATORS @FunctionalInterface //Added in Java8 version public interface Comparator<T> { int compare(T o1, T o2); //Java 8 adds loads of default methods }
  • 15. LAMBDA EXAMPLE 6 - COMPARATORS 2 List<Person> loadsOfPeople = ...; Pre Java 8: public class SortByPersonAge implements Comparator<Person> { public int compare(Person p1, Person p2) { return p1.getAge() - p2.getAge(); } } Collections.sort(loadsOfPeople, new SortByPersonAge()); Java 8: Collections.sort(loadsOfPeople, (p1, p2) -> p1.getAge() - p2.getAge());
  • 16. LAMBDA EXAMPLE 7 - COMPARATORS 3 As usual in Java 8... the Comparator interface provides plenty of useful default & static methods... //"comparing" static method simplifies creation Comparator<Person> newComparator = Comparator.comparing(e -> e.getIq()); //"thenComparing" combines comparators Collections.sort(loadsOfPeople, newComparator.thenComparing( Comparator.comparing(e -> e.getAge())));
  • 17. LAMBDA EXAMPLE 8 - COMPARATORS 4 and more... //More useful Collection methods... loadsOfPeople4.sort( Comparator.comparing(e -> e.getIq())); //And finally... Method references loadsOfPeople.sort( Comparator.comparing(Person::getAge));
  • 18. INTRODUCING METHOD REFERENCES Any method can be automatically “lifted” into a function. It must simply meet contract of the FunctionalInterface Can be easier to debug & test than Lambdas, more descriptive stack traces Promotes re-use, keeping code DRY Uses the "::" syntax
  • 19. METHOD REFERENCES TYPES Reference to... Example a static method Class::staticMethodName an instance method of a speci c object object::instanceMethodName an instance method of an arbitrary object Class::methodName a constructor ClassName::new
  • 20. REFERENCE TO A STATIC METHOD A simple reference to a static method //isPersonOver50 is a static method printMatchingPeople(loadsOfPeople, PersonPredicates::isPersonOver50); This is equivalent to printMatchingPeople(loadsOfPeople, x -> x.getAge() > 50);
  • 21. REFERENCE TO AN INSTANCE METHOD OF A SPECIFIC OBJECT A reference to a method on an object instance List<String> strings = ... //print is a method on the "out" PrintStream object strings.forEach(System.out::print); This is equivalent to strings.forEach(x -> System.out.print(x));
  • 22. REFERENCE TO AN INSTANCE METHOD OF AN ARBITRARY OBJECT Examine this simpli ed de nition of a map function public interface Function<T,R> { public R apply(T t); } public <T, R> List<R> map(Function<T, R> function, List<T> source) { /* applies the function to each element, converting it from T to R */ }
  • 23. REFERENCE TO AN INSTANCE METHOD OF AN ARBITRARY OBJECT CONT... Although it looks like we're referencing a Class method, we're invoking an instance method on the object(s) passed in the call List<Person> loadsOfPeople = ... List<Integer> namesOfPeople = map(Person::getAge, loadsOfPeople); This is equivalent to map(person -> person.getAge(), loadsOfPeople);
  • 24. REFERENCE TO A CONSTRUCTOR Uses the constructor to create new objects, the constructor signature must match that of the @FunctionalInterface List<String> digits = Arrays.asList("1", "2", "3"); //Transforms a String into a new Integer List<Integer> numbers = map(Integer::new, digits); This is equivalent to map(s -> new Integer(s), digits);
  • 25. WHAT'S WRONG WITH COLLECTIONS Every application uses Collections, however Collections are dif cult to query and aggregate, requiring several levels of iteration and conditionals, basically it’s messy and painful Writing multi-threaded code to do this manually is dif cult to write and maintain Imagine writing this manually Stream<String> words=Stream.of("Java", "8", "FTW"); Map<String, Long> letterToNumberOfOccurrences = words.map(w -> w.split("")) .flatMap(Arrays::stream) .collect(Collectors.groupingBy( Function.identity(), Collectors.counting())); //Prints: //{a=2, T=1, F=1, v=1, W=1, 8=1, J=1}
  • 26. INTRODUCING STREAMS! A Stream is a conceptually xed data structure in which elements are computed on demand Streams iterate internally, you don’t have to worry about handling the iteration Pipelining: Akin to the “pipe” command in unix, allowing aggregations to be chained together Automatic optimisation: short-circuiting and lazy processing Can be in nite Can be executed in parallel automatically using parallelStream or parallel()
  • 27. MORE STREAMS... Can be created from multiple sources: Arrays.stream(...), Stream.of(1, 2, 3, 4), Stream.iterate(...), Stream.range(...), Random.ints(), Files.lines(...)... Two types of operations: Intermediate (aggregation): lter, map, atMap, sorted ... Terminal: collect, reduce, forEach, ndAny ... Specialised Streams: IntStream, LongStream and DoubleStream: better performance for those unboxed types
  • 28. MAP public <R> Stream<R> map(Function<T, R> mapper); The mapper Function converts each element from T to R. The result is then added, as is, to the Stream
  • 29. FLATMAP public <R> Stream<R> flatMap(Function<T, Stream<R>> mapper); The mapper Function converts each element from T to a Stream of R This is the key difference to map, the function itself returns a Stream rather than one element This Stream is then attened (merged) into the main Stream To put it another way: atMap lets you replace each value of a Stream with another Stream, and then it concatenates all the generated streams into one single stream
  • 30. REDUCE public T reduce(T identity, BinaryOperator<T> accumulator); public Optional<T> reduce( BinaryOperator<T> accumulator); //This is the function contained in BinaryOperator R apply(T t, U u); Terminal Operation Takes a Stream of values and repeatedly applies the accumulator to reduce them into a single value The accumulator is passed the total so far (T) and the current element (U) If passed, identity provides the initial value, rather than the rst element
  • 31. REDUCE CONTINUED... int totalAgeUsingReduce = loadsOfPeople.stream() .map(Person::getAge) //contains 5, 10, 15 .reduce(0, (total, current) -> total + current); 1.First we map the Person to the age int 2.reduce then starts at 0, and adds the current element, 5 3.reduce continues by adding the current total 5, to the next element, 10 4. nally reduce adds the current total 15, to the next element 15 5.Tada, we've added up all the ages: 30!
  • 32. COLLECTORS The collect method is a terminal operation which takes various "recipes", called Collectors for accumulating the elements of a stream into a summary result, or converting to a speci c type (such as a List) List<String> listOfStrings = loadsOfPeople.stream() .map(x -> x.getName()) .collect(Collectors.toList()); The argument passed to collect is an object of type java .util.stream.Collector It describes how to accumulate the elements of a stream into a nal result Can be used for Grouping, Partitioning, Averaging, ...
  • 33. STREAMS EXAMPLE 1 List<Integer> numbers = Arrays.asList(1, 2 ... 8); List<Integer> twoEvenSquares = numbers.stream() .filter(n -> n % 2 == 0) //Filter odd numbers .map(n -> n * n) ////Multiply by itself .limit(2)//Limit to two results .collect(Collectors.toList()); //Finish! Imagine a println in each step... filtering 1 filtering 2 mapping 2 filtering 3 filtering 4 mapping 4
  • 35. STREAMS EXAMPLE 2 List<String> youngerPeopleSortedByIq = loadsOfPeople.stream() .filter(x -> x.getAge() < 50) .sorted(Comparator .comparing(Person::getIq).reversed()) .map(Person::getName) .collect(Collectors.toList()); 1. Filter out all people older than 50 2. Inverse sort the remaining people by IQ 3. map each person to their name (convert to a Stream<String>) 4. Convert the result to a List
  • 36. STREAMS EXAMPLE 3 - SUM int combinedAge = loadsOfPeople.stream() .mapToInt(Person::getAge) //returns IntStream .sum(); //this HAS to be a specialised Stream 1. map each person to their age, producing an IntStream 2. sum the results, also supports average
  • 37. STREAMS EXAMPLE 4 - MAP, REDUCE String xml = "<people>" + loadsOfPeople.stream() .map(x -> "<person>"+ x.getName() +"</person>") .reduce("", String::concat) //start with "" + "</people>"; map each Person to an XML element (<person>Steve</person>), then use String.concat to reduce the Stream into one XML String <people> <person>Dave</person> <person>Helen</person> <person>Laura</person> <person>Ben</person> </people>
  • 38. STREAMS EXAMPLE 5 - MAP List<Stream<Person>> clonedPeople = loadsOfPeople.stream() .map(person -> Stream.of(person, person.dolly())) .collect(Collectors.toList()); 1.map creates a new Stream containing two people 2.This Stream is then added to the main Stream as-is, leaving us with a pretty useless: List<Stream<Person>>
  • 39. STREAMS EXAMPLE 6 - FLATMAP List<Person> clonedPeople2 = loadsOfPeople.stream() .flatMap(person -> Stream.of(person, person.dolly())) .collect(Collectors.toList()); 1. atMap combines each element from the new Streams into one Stream<Person> 2.So now we've got what we wanted in the rst place, a List<Person> Sweeet!
  • 40. STREAMS EXAMPLE 7 - REDUCE int totalAgeUsingReduce = loadsOfPeople.stream() .map(Person::getAge) .reduce((total, current) -> total + current) .get(); //get the result from the Optional This is the same as the previous example, the difference being we don't specify a default value for reduce Not specifying a default value means the result is Optional... if the Stream is empty then so is the result!
  • 41. STREAMS EXAMPLE 8 - GROUPING Map<Integer, List<Person>> peopleGroupedByAge = loadsOfPeople.stream() .filter(x -> x.getIq() > 110) .collect(Collectors.groupingBy(Person::getAge)); The collect method groups the ltered results by age, producing a Map<age, <Person>> {52=[Person{... age=52, iq=113, gender=MALE}], 60=[Person{... age=60, iq=120, gender=FEMALE}], 28=[Person{... age=28, iq=190, gender=MALE}]}
  • 42. STREAMS EXAMPLE 9 - PARTITIONING Map<Boolean, List<Person>> peoplePartitionedByAge = loadsOfPeople.stream().filter(x -> x.getIq() > 110) .collect(Collectors .partitioningBy(x -> x.getAge() > 55)); The collect method partitions the ltered results by age The Map will have two entries, true and false, according to the Predicate {false=[Person{... age=28, iq=190, gender=MALE}], true=[Person{... age=60, iq=120, gender=FEMALE}]}
  • 43. STREAMS EXAMPLE 10 - MULTIPLE GROUPS Map<Integer, Double> peopleGroupedBySexAndAvgAge = loadsOfPeople.stream() .filter(x -> x.getIq() > 110) .collect( Collectors.groupingBy(Person::getAge, Collectors.averagingInt(Person::getIq))); We can group by multiple Collectors Here we group by age and the average IQ of that group {52=113.0, 60=117.5, 28=190.0}
  • 44. STREAMS EXAMPLE 11 - FINDANY loadsOfPeople.stream() .filter(t -> t.getGender() == Person.Sex.FEMALE) .findAny() .ifPresent(System.out::println); findAny either returns an element or nothing, hence we get an Optional ifPresent executes the Lambda if we get a result
  • 45. STREAMS EXAMPLE 12 - PARALLEL Lets iterate over 10,000,000 elements! x -> Stream.iterate(1L, i -> i + 1) .limit(x) .reduce(Long::sum).get(); Executes in 80ms - we incur a penalty here because the long is repeatedly boxed and unboxed Executes in 211ms?! It turns out parallel isn't always a free win! x -> Stream.iterate(1L, i -> i + 1) .parallel().limit(x) .reduce(Long::sum).get();
  • 46.
  • 47. STREAMS EXAMPLE 13 - PARALLEL WIN! x -> LongStream.rangeClosed(1L, x) .reduce(Long::sum).getAsLong(); Executes in 24ms - much better using an unboxed Stream Executes in 7ms - now that the Stream isn't dynamic, parallel works much better! x -> LongStream.rangeClosed(1L, x) .parallel() .reduce(Long::sum).getAsLong();
  • 48. OPTIONAL Use Optional instead of passing null around, helps prevent NullPointerExceptions Optional is a container that’s either empty or present, in which case it contains a value So anytime that you’re thinking of return or accepting a null value in a method, use Optional instead! public class Computer { private Optional<Mainboard> mainboard; } public class Mainboard { private Optional<Cpu> cpu; } public class Cpu { private String type; }
  • 49. USING OPTIONAL Several ways to create an Optional: Optional.of(cpu); //Throws an NPE if cpu is null Optional.ofNullable(cpu); //empty if cpu is null Getting the contents from the Optional: cpu.get(); //get CPU or throw NoSuchElementException cpu.orElse(new Cpu()); //safe get, provides default And more... cpu.isPresent(); //true if present, false if empty cpu.ifPresent(x -> System.out.println(x.getType())); Also supports map, atMap and lter!
  • 50. OPTIONAL EXAMPLE 1 - BASICS if (mainboard.isPresent() && mainboard.get().getCpu().isPresent()) { mainboard.get().getCpu().get().getType(); } Eww! Lets try something else! ***Fails to compile, calling getType on an Optional... if only we could atten it??? Optional<String> cpuType = mainboard.map(Mainboard::getCpu) .map(Cpu::getType); //Optional<Optional<Cpu>>
  • 51. OPTIONAL EXAMPLE 2 - FLATMAP Optional<String> stringOptional = mainboard .flatMap(Mainboard::getCpu) .map(Cpu::getType); Lets take this further and safely get cpu type of a Computer! Computer computer = new Computer(mainboard); String cpu = computer.getMainboard() .flatMap(Mainboard::getCpu) .map(Cpu::getType) .filter(x -> "Intel".equals(x)) .orElse("Nothing we're interested in!");
  • 52. IT'S BEEN EMOTIONAL... Slides at Source at Follow me markglh.github.io/Java8Madlab-Slides github.com/markglh/Java8Madlab-Examples @markglh
  • 53. RECOMMENDED READING Lambdas Part 1 (Ted Neward) Lambdas Part 2 (Ted Neward) Lambda Expressions vs Method References (Edwin Dalorzo) Youtube: Java 8 - more readable and exible code (Raoul- Gabriel Urma) Youtube: Lambda Expressions & Streams (Adib Saikali) Java 8 Streams Part 1 (Raoul-Gabriel Urma) Java 8 Streams Part 2 (Raoul-Gabriel Urma) Optional - No more NPE's (Raoul-Gabriel Urma)