SlideShare ist ein Scribd-Unternehmen logo
1 von 107
Downloaden Sie, um offline zu lesen
Collectors in the
Wild
@JosePaumard
Collectors?
Why should we be interested in collectors?
▪ They are part of the Stream API
▪ And kind of left aside…
Collectors?
YouTube:
▪ Stream tutorials ~700k
▪ Collectors tutorials < 5k
Collectors?
Why should we be interested in collectors?
▪ They are part of the Stream API
▪ And kind of left aside…
And it’s a pity because it is a very powerful API
@JosePaumard
Microsoft Virtual Academy
Questions?
#ColJ8
movies.stream()
.flatMap(movie -> movie.actors().stream())
.collect(
Collectors.groupingBy(
Function.identity(),
Collectors.counting()
)
)
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.get();
movies.stream()
.collect(
Collectors.groupingBy(
movie -> movie.releaseYear(),
Collector.of(
() -> new HashMap<Actor, AtomicLong>(),
(map, movie) -> {
movie.actors().forEach(
actor -> map.computeIfAbsent(actor, a -> new AtomicLong()).incrementAndGet()
) ;
},
(map1, map2) -> {
map2.entrySet().stream().forEach(
entry -> map1.computeIfAbsent(entry.getKey(), a -> new AtomicLong()).addAndGet(entry.getValue().get())
) ;
return map1 ;
},
new Collector.Characteristics [] {
Collector.Characteristics.CONCURRENT.CONCURRENT
}
)
)
)
.entrySet().stream()
.collect(
Collectors.toMap(
entry5 -> entry5.getKey(),
entry5 -> entry5.getValue()
.entrySet().stream()
.max(Map.Entry.comparingByValue(Comparator.comparing(l -> l.get())))
.get()
)
)
.entrySet()
.stream()
.max(Comparator.comparing(entry -> entry.getValue().getValue().get()))
.get();
Do not give bugs a place to
hide!
Brian Goetz
Collectors?
Why should we be interested in collectors?
▪ They are part of the Stream API
▪ And kind of left aside…
And it’s a pity because it is a very powerful API
▪ Even if we can also write unreadable code with it!
Agenda
Quick overview about streams
About collectors
Extending existing collectors
Making a collector readable
Creating new collectors
Composing Collectors
A Few Words on Streams
About Streams
A Stream:
▪ Is an object that connects to a source
▪ Has intermediate & terminal operations
▪ Some of the terminal operations can be collectors
▪ A collector can take more collectors as
parameters
A Stream is…
An object that connects to a source of data and
watch them flow
There is no data « in » a stream ≠ collection
stream
About Streams
On a stream:
▪ Any operation can be modeled with a collector
▪ Why is it interesting?
stream.collect(collector);
Intermediate Operations
stream
1st operation: mapping = changing the type
stream
2nd operation: filtering = removing some objects
3rd operation: flattening
stream
stream
3rd operation: flattening
Map, Filter, FlatMap
Three operations that do not need any buffer
to work
Not the case of all the operations…
Sorting elements using a comparator
The stream needs to see all the elements
before beginning to transmit them
stream
stream
Distinct
The Stream needs to remember all the
elements before transmitting them (or not)
Distinct, sorted
Both operations need a buffer to store all the
elements from the source
Intermediate Operations
2 categories:
- Stateless operations = do not need to
remember anything
- Stateful operations = do need a buffer
Limit and Skip
Two methods that rely on the order of the
elements:
- Limit = keeps the n first elements
- Skip = skips the n first elements
Needs to keep track of the index of the
elements and to process them in order
Terminal Operations
Intermediate vs Terminal
Only a terminal operation triggers the
consuming of the data from the source
movies.stream()
.filter(movie -> movie.releaseYear() == 2007)
.flatMap(movie -> movie.actors().stream())
.map(movie -> movie.getTitle());
Intermediate vs Terminal
Only a terminal operation triggers the
consuming of the data from the source
movies.stream()
.filter(movie -> movie.releaseYear() == 2007)
.flatMap(movie -> movie.actors().stream())
.map(movie -> movie.getTitle())
.forEach(movie -> System.out.println(movie.getTitle()));
Terminal Operations
First batch:
- forEach
- count
- max, min
- reduce
- toArray
Terminal Operations
First batch:
- forEach
- count
- max, min
- reduce
- toArray
Will consume all the data
Terminal Operations
Second Batch:
- allMatch
- anyMatch
- noneMatch
- findFirst
- findAny
Terminal Operations
Second Batch:
- allMatch
- anyMatch
- noneMatch
- findFirst
- findAny
Do not need to consume
all the data = short-circuit
operations
Terminal Operations
Special cases:
- max
- min
- reduce
Returns an Optional (to handle empty streams)
https://www.youtube.com/watch?v=Ej0sss6cq14@StuartMarks
A First Collector
And then there is collect!
The most seen:
Takes a collector as a parameter
List<String> result =
strings.stream()
.filter(s -> s.itEmpty())
.collect(Collectors.toList());
A First Collector (bis)
And then there is collect!
The most seen:
Takes a collector as a parameter
Set<String> result =
strings.stream()
.filter(s -> s.itEmpty())
.collect(Collectors.toSet());
A Second Collector
And then there is collect!
Maybe less known?:
Takes a collector as a parameter
String authors =
authors.stream()
.map(Author::getName)
.collect(Collectors.joining(", "));
Demo Time
A Third Collector
Creating a Map
Map<Integer, List<String>> result =
strings.stream()
.filter(s -> !s.isEmpty())
.collect(
Collectors.groupingBy(
s -> s.length()
)
);
3
4
5
one, two, three, four, five, six, seven, eight, nine, ten
one, two, six, ten
four, five, nine
three, seven, eight
groupingBy(String::length)



Map<Integer, List<String>>
3
4
5
one, two, three, four, five, six, seven, eight, nine, ten
one, two, six, ten
four, five, nine
three, seven, eight
groupingBy(String::length, downstream)



.stream().collect(downstream)
.stream().collect(downstream)
.stream().collect(downstream)
3
4
5
one, two, three, four, five, six, seven, eight, nine, ten
one, two, six, ten
four, five, nine
three, seven, eight
groupingBy(String::length, Collectors.counting())



4L
3L
3L
Map<Integer, Long>
A Third Collector (bis)
Creating a Map
Map<Integer, Long> result =
strings.stream()
.filter(s -> s.itEmpty())
.collect(
Collectors.groupingBy(
s -> s.length(), Collectors.counting()
)
);
Demo Time
A Collector that Counts
Number of articles per author
Gent & Walsh, Beyond NP: The QSAT Phase Transition
Gent & Hoos & Prosser & Walsh, Morphing: Combining…
A1 A2
Gent
Walsh
Gent
Hoos
Prosser
Walsh
flatMap(Article::getAuthors)
Gent & Walsh, Beyond NP: The QSAT Phase Transition
Gent & Hoos & Prosser & Walsh, Morphing: Combining…
Gent, Walsh, Gent, Hoos, Prosser, Walsh
flatMap(Article::getAuthors)
Gent
Walsh
Hoos



2L
2L
1L
Prosser  1L
groupingBy(
)
groupingBy(
identity(),
counting()
)
groupingBy(
identity(),
)
Demo Time
Supply, Accumulate and
Combine
Creating Lists
A closer look at that code:
List<String> result =
strings.stream()
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
stream a b b
collector
1) Build the list
2) Add elements one
by one
a b c
ArrayList
Creating Lists
1) Building the list: supplier
2) Adding an element to that list: accumulator
Supplier<List> supplier = () -> new ArrayList();
BiConsumer<List<E>, E> accumulator = (list, e) -> list.add(e);
In parallel
Stream
Collector
collector
1) Build a list
2) Add elements one
by one
3) Merge the lists
CPU 2
Stream
Collector
CPU 1
Creating Lists
1) Building the list: supplier
2) Adding an element to that list: accumulator
3) Combining two lists
Supplier<List> supplier = ArrayList::new;
BiConsumer<List<E>, E> accumulator = List::add;
BiConsumer<List<E>, List<E>> combiner = List::addAll;
Creating Lists
So we have:
List<String> result =
strings.stream()
.filter(s -> !s.isEmpty())
.collect(ArrayList::new,
List::add,
List::adAll);
Creating Lists
So we have:
List<String> result =
strings.stream()
.filter(s -> !s.isEmpty())
.collect(ArrayList::new,
Collection::add,
Collection::adAll);
Creating Sets
Almost the same:
Set<String> result =
strings.stream()
.filter(s -> !s.isEmpty())
.collect(HashSet::new,
Collection::add,
Collection::adAll);
String Concatenation
Now we need to create a String by
concatenating the elements using a separator:
« one, two, six »
Works with Streams of Strings
String Concatenation
Let us collect
strings.stream()
.filter(s -> s.length() == 3)
.collect(() -> new String(),
(finalString, s) -> finalString.concat(s),
(s1, s2) -> s1.concat(s2));
String Concatenation
Let us collect
strings.stream()
.filter(s -> s.length() == 3)
.collect(() -> new String(),
(finalString, s) -> finalString.concat(s),
(s1, s2) -> s1.concat(s2));
String Concatenation
Let us collect
strings.stream()
.filter(s -> s.length() == 3)
.collect(() -> new StringBuilder(),
(sb, s) -> sb.append(s),
(sb1, sb2) -> sb1.append(sb2));
String Concatenation
Let us collect
strings.stream()
.filter(s -> s.length() == 3)
.collect(StringBuilder::new,
StringBuilder::append,
StringBuilder::append);
String Concatenation
Let us collect
StringBuilder stringBuilder =
strings.stream()
.filter(s -> s.length() == 3)
.collect(StringBuilder::new,
StringBuilder::append,
StringBuilder::append);
String Concatenation
Let us collect
String string =
strings.stream()
.filter(s -> s.length() == 3)
.collect(StringBuilder::new,
StringBuilder::append,
StringBuilder::append)
.toString();
A Collector is…
3 Operations
- Supplier: creates the mutable container
- Accumulator
- Combiner
A Collector is…
3 + 1 Operations
- Supplier: creates the mutable container
- Accumulator
- Combiner
- Finisher, that can be the identity function
Collecting and Then
And we have a collector for that!
strings.stream()
.filter(s -> s.length() == 3)
.collect(
Collectors.collectingAndThen(
collector,
finisher // Function
)
);
Demo Time
7634L {2004, 7634L}
Map<Long, List<Entry<Integer, Long>>>
7634L {2004, 7634L}
Map<Long, List<Entry<Integer, Long>>>
Entry<Integer, Long> -> Integer = mapping
7634L {2004, 7634L}
Map<Long, List<Entry<Integer, Long>>>
Entry<Integer, Long> -> Integer = mapping
Function<> mapper = entry -> entry.getKey();
Collectors.mapping(mapper, toList());
Demo Time
Collect toMap
Useful for remapping maps
Do not generate duplicate keys!
map.entrySet().stream()
.collect(
Collectors.toMap(
entry -> entry.getKey(),
entry -> // create a new value
)
);
Custom Collectors:
1) Filter, Flat Map
2) Joins
3) Composition
Coffee break!
About Types
The Collector Interface
public interface Collector<T, A, R> {
public Supplier<A> supplier(); // A: mutable container
public BiConsumer<A, T> accumulator(); // T: processed elments
public BinaryOperator<A> combiner(); // Often the type returned
public Function<A, R> finisher(); // Final touch
}
The Collector Interface
public interface Collector<T, A, R> {
public Supplier<A> supplier(); // A: mutable container
public BiConsumer<A, T> accumulator(); // T: processed elments
public BinaryOperator<A> combiner(); // Often the type returned
public Function<A, R> finisher(); // Final touch
public Set<Characteristics> characteristics();
}
Type of a Collector
In a nutshell:
- T: type of the elements of the stream
- A: type the mutable container
- R: type of the final container
We often have A = R
The finisher may be the identity function
≠
one, two, three, four, five, six, seven, eight, nine, ten
groupingBy(String::length)
3
4
5
one, two, six, ten
four, five, nine
three, seven, eight



one, two, three, four, five, six, seven, eight, nine, ten
Collector<String, ?, Map<Integer, List<String>> > c =
groupingBy(String::length)
3
4
5
one, two, six, ten
four, five, nine
three, seven, eight



one, two, three, four, five, six, seven, eight, nine, ten
Collector<String, ?, Map<Integer, List<String>> > c =
groupingBy(String::length)
3
4
5
one, two, six, ten
four, five, nine
three, seven, eight



one, two, three, four, five, six, seven, eight, nine, ten
Collector<String, ?, Map<Integer, List<String>> > c =
groupingBy(String::length)
3
4
5
one, two, six, ten
four, five, nine
three, seven, eight



one, two, three, four, five, six, seven, eight, nine, ten
Collector<String, ?, Map<Integer, List<String>> > c =
groupingBy(
String::length,
?
)
3
4
5
one, two, six, ten
four, five, nine
three, seven, eight



one, two, three, four, five, six, seven, eight, nine, ten
Collector<String, ?, Map<Integer, List<String>> > c =
groupingBy(
String::length,
Collector<String, ?, >
)
3
4
5
one, two, six, ten
four, five, nine
three, seven, eight



one, two, three, four, five, six, seven, eight, nine, ten
Collector<String, ?, Map<Integer, Value>> c =
groupingBy(
String::length,
Collector<String, ?, Value>
)
counting() : Collector<T, ?, Long>
3
4
5
4L
3L
3L



Intermediate Operations
Intermediate Collectors
Back to the mapping collector
This collector takes a downstream collector
stream.collect(mapping(function, downstream));
Intermediate Collectors
The mapping Collector provides an
intermediate operation
stream.collect(mapping(function, downstream));
Intermediate Collectors
The mapping Collector provides an
intermediate operation
Why is it interesting?
To create downstream collectors!
So what about integrating all our stream
processing as a collector?
stream.collect(mapping(function, downstream));
Intermediate Collectors
If collectors can map, why would’nt they filter,
or flatMap?
…in fact they can in 9 ☺
Intermediate Collectors
The mapping Collector provides an
intermediate operation
We have a Stream<T>
So predicate is a Predicate<T>
Downstream is a Collector<T, ?, R>
stream.collect(mapping(function, downstream));
stream.collect(filtering(predicate, downstream));
Intermediate Collectors
The mapping Collector provides an
intermediate operation
We have a Stream<T>
So flatMapper is a Function<T, Stream<TT>>
And downstream is a Collector<TT, ?, R>
stream.collect(mapping(function, downstream));
stream.collect(flatMapping(flatMapper, downstream));
Demo Time
Characteristics
Three characteristics for the collectors:
- IDENTITY_FINISH: the finisher is the identity
function
- UNORDERED: the collector does not preserve
the order of the elements
- CONCURRENT: the collector is thread safe
Handling Empty Optionals
Two things:
- Make an Optional a Stream
- Remove the empty Streams with flatMap
Map<K, Optional<V>> // with empty Optionals...
-> Map<K, Steam<V>> // with empty Streams
-> Stream<Map.Entry<K, V>> // the empty are gone
-> Map<K, V> // using a toMap
Joins
1) The authors that published the most
together
2) The authors that published the most
together in a year
StreamsUtils to the rescue!
Gent & Walsh, Beyond NP: The QSAT Phase Transition
Gent & Hoos & Prosser & Walsh, Morphing: Combining…
Gent, Hoos, Prosser, Walsh
Gent, Walsh
{Gent, Walsh}
{Gent, Hoos} {Gent, Prosser} {Gent, Walsh}
{Hoos, Prosser} {Hoos, Walsh}
{Prosser, Walsh}
flatMap()
Demo Time
Application
What is interesting in modeling a processing as
a collector?
We can reuse this collector as a downstream
collector for other processings
What About Readability?
Creating composable Collectors
Demo Time
Dealing with Issues
The main issue is the empty stream
A whole stream may have elements
But when we build an histogram, a given
substream may become empty…
Conclusion
API Collector
A very rich API indeed
Quite complex…
One needs to have a very precise idea of the
data processing pipeline
Can be extended!
API Collector
A collector can model a whole processing
Once it is written, it can be passed as a
downstream to another processing pipeline
Can be made composable to improve
readability
https://github.com/JosePaumard
Thank you for your
attention!
Questions?
@JosePaumard
https://github.com/JosePaumard
https://www.slideshare.net/jpaumard
https://www.youtube.com/user/JPaumard

Weitere ähnliche Inhalte

Was ist angesagt?

Java 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsJava 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsNewCircle Training
 
Declarative Concurrency with Reactive Programming
Declarative Concurrency with Reactive ProgrammingDeclarative Concurrency with Reactive Programming
Declarative Concurrency with Reactive ProgrammingFlorian Stefan
 
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 InterfacesGanesh Samarthyam
 
Java 9 Module System Introduction
Java 9 Module System IntroductionJava 9 Module System Introduction
Java 9 Module System IntroductionDan Stine
 
Kotlin for Android Development
Kotlin for Android DevelopmentKotlin for Android Development
Kotlin for Android DevelopmentSpeck&Tech
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesVMware Tanzu
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
 
Java collections concept
Java collections conceptJava collections concept
Java collections conceptkumar gaurav
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsYura Nosenko
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New FeaturesHaim Michael
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKJosé Paumard
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 

Was ist angesagt? (20)

Java 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsJava 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & Streams
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
Declarative Concurrency with Reactive Programming
Declarative Concurrency with Reactive ProgrammingDeclarative Concurrency with Reactive Programming
Declarative Concurrency with Reactive Programming
 
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
 
Java 9 Module System Introduction
Java 9 Module System IntroductionJava 9 Module System Introduction
Java 9 Module System Introduction
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Kotlin for Android Development
Kotlin for Android DevelopmentKotlin for Android Development
Kotlin for Android Development
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
Java collections concept
Java collections conceptJava collections concept
Java collections concept
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Java I/O
Java I/OJava I/O
Java I/O
 

Ähnlich wie Collectors in the Wild

Legacy lambda code
Legacy lambda codeLegacy lambda code
Legacy lambda codePeter Lawrey
 
How to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaHow to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaEdureka!
 
Collections in Java
Collections in JavaCollections in Java
Collections in JavaKhasim Cise
 
Retro gaming with lambdas stephen chin
Retro gaming with lambdas   stephen chinRetro gaming with lambdas   stephen chin
Retro gaming with lambdas stephen chinNLJUG
 
Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams IndicThreads
 
18. Java associative arrays
18. Java associative arrays18. Java associative arrays
18. Java associative arraysIntro C# Book
 
CON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptx
CON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptxCON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptx
CON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptxskypy045
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2JollyRogers5
 
Java Foundations: Maps, Lambda and Stream API
Java Foundations: Maps, Lambda and Stream APIJava Foundations: Maps, Lambda and Stream API
Java Foundations: Maps, Lambda and Stream APISvetlin Nakov
 
Let if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and moreLet if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and moreBhakti Mehta
 
Functional Programming in Java 8
Functional Programming in Java 8Functional Programming in Java 8
Functional Programming in Java 8宇 傅
 
Java 8 lambda expressions
Java 8 lambda expressionsJava 8 lambda expressions
Java 8 lambda expressionsLogan Chien
 
Coherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherenceCoherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherencearagozin
 
Data Structures by Maneesh Boddu
Data Structures by Maneesh BodduData Structures by Maneesh Boddu
Data Structures by Maneesh Boddumaneesh boddu
 

Ähnlich wie Collectors in the Wild (20)

Legacy lambda code
Legacy lambda codeLegacy lambda code
Legacy lambda code
 
How to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaHow to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | Edureka
 
collections
collectionscollections
collections
 
Collections
CollectionsCollections
Collections
 
Practical cats
Practical catsPractical cats
Practical cats
 
Java 8 Streams
Java 8 StreamsJava 8 Streams
Java 8 Streams
 
Collections
CollectionsCollections
Collections
 
Collections in Java
Collections in JavaCollections in Java
Collections in Java
 
Retro gaming with lambdas stephen chin
Retro gaming with lambdas   stephen chinRetro gaming with lambdas   stephen chin
Retro gaming with lambdas stephen chin
 
Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams
 
18. Java associative arrays
18. Java associative arrays18. Java associative arrays
18. Java associative arrays
 
JAVA PROGRAMMING - The Collections Framework
JAVA PROGRAMMING - The Collections Framework JAVA PROGRAMMING - The Collections Framework
JAVA PROGRAMMING - The Collections Framework
 
CON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptx
CON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptxCON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptx
CON5423-GS-Collections-and-Java-8-Functional-Fluent-Friendly-and-Fun.pptx
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
 
Java Foundations: Maps, Lambda and Stream API
Java Foundations: Maps, Lambda and Stream APIJava Foundations: Maps, Lambda and Stream API
Java Foundations: Maps, Lambda and Stream API
 
Let if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and moreLet if flow: Java 8 Streams puzzles and more
Let if flow: Java 8 Streams puzzles and more
 
Functional Programming in Java 8
Functional Programming in Java 8Functional Programming in Java 8
Functional Programming in Java 8
 
Java 8 lambda expressions
Java 8 lambda expressionsJava 8 lambda expressions
Java 8 lambda expressions
 
Coherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherenceCoherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherence
 
Data Structures by Maneesh Boddu
Data Structures by Maneesh BodduData Structures by Maneesh Boddu
Data Structures by Maneesh Boddu
 

Mehr von 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
 
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
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé 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
 
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 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
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full storyJosé 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
 
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
 

Mehr von José Paumard (20)

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
 
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
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
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!
 
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 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
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full story
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
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
 
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
 

Kürzlich hochgeladen

Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxVishalSingh1417
 
Unit-IV; Professional Sales Representative (PSR).pptx
Unit-IV; Professional Sales Representative (PSR).pptxUnit-IV; Professional Sales Representative (PSR).pptx
Unit-IV; Professional Sales Representative (PSR).pptxVishalSingh1417
 
Accessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactAccessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactdawncurless
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docxPoojaSen20
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactPECB
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introductionMaksud Ahmed
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17Celine George
 
SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...
SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...
SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...KokoStevan
 
Gardella_Mateo_IntellectualProperty.pdf.
Gardella_Mateo_IntellectualProperty.pdf.Gardella_Mateo_IntellectualProperty.pdf.
Gardella_Mateo_IntellectualProperty.pdf.MateoGardella
 
PROCESS RECORDING FORMAT.docx
PROCESS      RECORDING        FORMAT.docxPROCESS      RECORDING        FORMAT.docx
PROCESS RECORDING FORMAT.docxPoojaSen20
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphThiyagu K
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...christianmathematics
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsTechSoup
 
Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Disha Kariya
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfagholdier
 
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...Shubhangi Sonawane
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAssociation for Project Management
 
Class 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfClass 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfAyushMahapatra5
 

Kürzlich hochgeladen (20)

Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
Unit-IV; Professional Sales Representative (PSR).pptx
Unit-IV; Professional Sales Representative (PSR).pptxUnit-IV; Professional Sales Representative (PSR).pptx
Unit-IV; Professional Sales Representative (PSR).pptx
 
Accessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactAccessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impact
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docx
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global Impact
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...
SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...
SECOND SEMESTER TOPIC COVERAGE SY 2023-2024 Trends, Networks, and Critical Th...
 
Gardella_Mateo_IntellectualProperty.pdf.
Gardella_Mateo_IntellectualProperty.pdf.Gardella_Mateo_IntellectualProperty.pdf.
Gardella_Mateo_IntellectualProperty.pdf.
 
Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1
 
PROCESS RECORDING FORMAT.docx
PROCESS      RECORDING        FORMAT.docxPROCESS      RECORDING        FORMAT.docx
PROCESS RECORDING FORMAT.docx
 
Advance Mobile Application Development class 07
Advance Mobile Application Development class 07Advance Mobile Application Development class 07
Advance Mobile Application Development class 07
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across Sectors
 
Class 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfClass 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdf
 

Collectors in the Wild

  • 2. Collectors? Why should we be interested in collectors? ▪ They are part of the Stream API ▪ And kind of left aside…
  • 3. Collectors? YouTube: ▪ Stream tutorials ~700k ▪ Collectors tutorials < 5k
  • 4. Collectors? Why should we be interested in collectors? ▪ They are part of the Stream API ▪ And kind of left aside… And it’s a pity because it is a very powerful API
  • 8. movies.stream() .collect( Collectors.groupingBy( movie -> movie.releaseYear(), Collector.of( () -> new HashMap<Actor, AtomicLong>(), (map, movie) -> { movie.actors().forEach( actor -> map.computeIfAbsent(actor, a -> new AtomicLong()).incrementAndGet() ) ; }, (map1, map2) -> { map2.entrySet().stream().forEach( entry -> map1.computeIfAbsent(entry.getKey(), a -> new AtomicLong()).addAndGet(entry.getValue().get()) ) ; return map1 ; }, new Collector.Characteristics [] { Collector.Characteristics.CONCURRENT.CONCURRENT } ) ) ) .entrySet().stream() .collect( Collectors.toMap( entry5 -> entry5.getKey(), entry5 -> entry5.getValue() .entrySet().stream() .max(Map.Entry.comparingByValue(Comparator.comparing(l -> l.get()))) .get() ) ) .entrySet() .stream() .max(Comparator.comparing(entry -> entry.getValue().getValue().get())) .get();
  • 9. Do not give bugs a place to hide! Brian Goetz
  • 10. Collectors? Why should we be interested in collectors? ▪ They are part of the Stream API ▪ And kind of left aside… And it’s a pity because it is a very powerful API ▪ Even if we can also write unreadable code with it!
  • 11. Agenda Quick overview about streams About collectors Extending existing collectors Making a collector readable Creating new collectors Composing Collectors
  • 12. A Few Words on Streams
  • 13. About Streams A Stream: ▪ Is an object that connects to a source ▪ Has intermediate & terminal operations ▪ Some of the terminal operations can be collectors ▪ A collector can take more collectors as parameters
  • 14. A Stream is… An object that connects to a source of data and watch them flow There is no data « in » a stream ≠ collection stream
  • 15. About Streams On a stream: ▪ Any operation can be modeled with a collector ▪ Why is it interesting? stream.collect(collector);
  • 17. stream 1st operation: mapping = changing the type
  • 18. stream 2nd operation: filtering = removing some objects
  • 21. Map, Filter, FlatMap Three operations that do not need any buffer to work Not the case of all the operations…
  • 22. Sorting elements using a comparator The stream needs to see all the elements before beginning to transmit them stream
  • 23. stream Distinct The Stream needs to remember all the elements before transmitting them (or not)
  • 24. Distinct, sorted Both operations need a buffer to store all the elements from the source
  • 25. Intermediate Operations 2 categories: - Stateless operations = do not need to remember anything - Stateful operations = do need a buffer
  • 26. Limit and Skip Two methods that rely on the order of the elements: - Limit = keeps the n first elements - Skip = skips the n first elements Needs to keep track of the index of the elements and to process them in order
  • 28. Intermediate vs Terminal Only a terminal operation triggers the consuming of the data from the source movies.stream() .filter(movie -> movie.releaseYear() == 2007) .flatMap(movie -> movie.actors().stream()) .map(movie -> movie.getTitle());
  • 29. Intermediate vs Terminal Only a terminal operation triggers the consuming of the data from the source movies.stream() .filter(movie -> movie.releaseYear() == 2007) .flatMap(movie -> movie.actors().stream()) .map(movie -> movie.getTitle()) .forEach(movie -> System.out.println(movie.getTitle()));
  • 30. Terminal Operations First batch: - forEach - count - max, min - reduce - toArray
  • 31. Terminal Operations First batch: - forEach - count - max, min - reduce - toArray Will consume all the data
  • 32. Terminal Operations Second Batch: - allMatch - anyMatch - noneMatch - findFirst - findAny
  • 33. Terminal Operations Second Batch: - allMatch - anyMatch - noneMatch - findFirst - findAny Do not need to consume all the data = short-circuit operations
  • 34. Terminal Operations Special cases: - max - min - reduce Returns an Optional (to handle empty streams) https://www.youtube.com/watch?v=Ej0sss6cq14@StuartMarks
  • 35. A First Collector And then there is collect! The most seen: Takes a collector as a parameter List<String> result = strings.stream() .filter(s -> s.itEmpty()) .collect(Collectors.toList());
  • 36. A First Collector (bis) And then there is collect! The most seen: Takes a collector as a parameter Set<String> result = strings.stream() .filter(s -> s.itEmpty()) .collect(Collectors.toSet());
  • 37. A Second Collector And then there is collect! Maybe less known?: Takes a collector as a parameter String authors = authors.stream() .map(Author::getName) .collect(Collectors.joining(", "));
  • 39. A Third Collector Creating a Map Map<Integer, List<String>> result = strings.stream() .filter(s -> !s.isEmpty()) .collect( Collectors.groupingBy( s -> s.length() ) );
  • 40. 3 4 5 one, two, three, four, five, six, seven, eight, nine, ten one, two, six, ten four, five, nine three, seven, eight groupingBy(String::length)    Map<Integer, List<String>>
  • 41. 3 4 5 one, two, three, four, five, six, seven, eight, nine, ten one, two, six, ten four, five, nine three, seven, eight groupingBy(String::length, downstream)    .stream().collect(downstream) .stream().collect(downstream) .stream().collect(downstream)
  • 42. 3 4 5 one, two, three, four, five, six, seven, eight, nine, ten one, two, six, ten four, five, nine three, seven, eight groupingBy(String::length, Collectors.counting())    4L 3L 3L Map<Integer, Long>
  • 43. A Third Collector (bis) Creating a Map Map<Integer, Long> result = strings.stream() .filter(s -> s.itEmpty()) .collect( Collectors.groupingBy( s -> s.length(), Collectors.counting() ) );
  • 45. A Collector that Counts Number of articles per author
  • 46. Gent & Walsh, Beyond NP: The QSAT Phase Transition Gent & Hoos & Prosser & Walsh, Morphing: Combining… A1 A2 Gent Walsh Gent Hoos Prosser Walsh flatMap(Article::getAuthors)
  • 47. Gent & Walsh, Beyond NP: The QSAT Phase Transition Gent & Hoos & Prosser & Walsh, Morphing: Combining… Gent, Walsh, Gent, Hoos, Prosser, Walsh flatMap(Article::getAuthors) Gent Walsh Hoos    2L 2L 1L Prosser  1L groupingBy( ) groupingBy( identity(), counting() ) groupingBy( identity(), )
  • 50. Creating Lists A closer look at that code: List<String> result = strings.stream() .filter(s -> !s.isEmpty()) .collect(Collectors.toList());
  • 51. stream a b b collector 1) Build the list 2) Add elements one by one a b c ArrayList
  • 52. Creating Lists 1) Building the list: supplier 2) Adding an element to that list: accumulator Supplier<List> supplier = () -> new ArrayList(); BiConsumer<List<E>, E> accumulator = (list, e) -> list.add(e);
  • 53. In parallel Stream Collector collector 1) Build a list 2) Add elements one by one 3) Merge the lists CPU 2 Stream Collector CPU 1
  • 54. Creating Lists 1) Building the list: supplier 2) Adding an element to that list: accumulator 3) Combining two lists Supplier<List> supplier = ArrayList::new; BiConsumer<List<E>, E> accumulator = List::add; BiConsumer<List<E>, List<E>> combiner = List::addAll;
  • 55. Creating Lists So we have: List<String> result = strings.stream() .filter(s -> !s.isEmpty()) .collect(ArrayList::new, List::add, List::adAll);
  • 56. Creating Lists So we have: List<String> result = strings.stream() .filter(s -> !s.isEmpty()) .collect(ArrayList::new, Collection::add, Collection::adAll);
  • 57. Creating Sets Almost the same: Set<String> result = strings.stream() .filter(s -> !s.isEmpty()) .collect(HashSet::new, Collection::add, Collection::adAll);
  • 58. String Concatenation Now we need to create a String by concatenating the elements using a separator: « one, two, six » Works with Streams of Strings
  • 59. String Concatenation Let us collect strings.stream() .filter(s -> s.length() == 3) .collect(() -> new String(), (finalString, s) -> finalString.concat(s), (s1, s2) -> s1.concat(s2));
  • 60. String Concatenation Let us collect strings.stream() .filter(s -> s.length() == 3) .collect(() -> new String(), (finalString, s) -> finalString.concat(s), (s1, s2) -> s1.concat(s2));
  • 61. String Concatenation Let us collect strings.stream() .filter(s -> s.length() == 3) .collect(() -> new StringBuilder(), (sb, s) -> sb.append(s), (sb1, sb2) -> sb1.append(sb2));
  • 62. String Concatenation Let us collect strings.stream() .filter(s -> s.length() == 3) .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
  • 63. String Concatenation Let us collect StringBuilder stringBuilder = strings.stream() .filter(s -> s.length() == 3) .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
  • 64. String Concatenation Let us collect String string = strings.stream() .filter(s -> s.length() == 3) .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) .toString();
  • 65. A Collector is… 3 Operations - Supplier: creates the mutable container - Accumulator - Combiner
  • 66. A Collector is… 3 + 1 Operations - Supplier: creates the mutable container - Accumulator - Combiner - Finisher, that can be the identity function
  • 67. Collecting and Then And we have a collector for that! strings.stream() .filter(s -> s.length() == 3) .collect( Collectors.collectingAndThen( collector, finisher // Function ) );
  • 69. 7634L {2004, 7634L} Map<Long, List<Entry<Integer, Long>>>
  • 70. 7634L {2004, 7634L} Map<Long, List<Entry<Integer, Long>>> Entry<Integer, Long> -> Integer = mapping
  • 71. 7634L {2004, 7634L} Map<Long, List<Entry<Integer, Long>>> Entry<Integer, Long> -> Integer = mapping Function<> mapper = entry -> entry.getKey(); Collectors.mapping(mapper, toList());
  • 73. Collect toMap Useful for remapping maps Do not generate duplicate keys! map.entrySet().stream() .collect( Collectors.toMap( entry -> entry.getKey(), entry -> // create a new value ) );
  • 74. Custom Collectors: 1) Filter, Flat Map 2) Joins 3) Composition Coffee break!
  • 76. The Collector Interface public interface Collector<T, A, R> { public Supplier<A> supplier(); // A: mutable container public BiConsumer<A, T> accumulator(); // T: processed elments public BinaryOperator<A> combiner(); // Often the type returned public Function<A, R> finisher(); // Final touch }
  • 77. The Collector Interface public interface Collector<T, A, R> { public Supplier<A> supplier(); // A: mutable container public BiConsumer<A, T> accumulator(); // T: processed elments public BinaryOperator<A> combiner(); // Often the type returned public Function<A, R> finisher(); // Final touch public Set<Characteristics> characteristics(); }
  • 78. Type of a Collector In a nutshell: - T: type of the elements of the stream - A: type the mutable container - R: type of the final container We often have A = R The finisher may be the identity function ≠
  • 79. one, two, three, four, five, six, seven, eight, nine, ten groupingBy(String::length) 3 4 5 one, two, six, ten four, five, nine three, seven, eight   
  • 80. one, two, three, four, five, six, seven, eight, nine, ten Collector<String, ?, Map<Integer, List<String>> > c = groupingBy(String::length) 3 4 5 one, two, six, ten four, five, nine three, seven, eight   
  • 81. one, two, three, four, five, six, seven, eight, nine, ten Collector<String, ?, Map<Integer, List<String>> > c = groupingBy(String::length) 3 4 5 one, two, six, ten four, five, nine three, seven, eight   
  • 82. one, two, three, four, five, six, seven, eight, nine, ten Collector<String, ?, Map<Integer, List<String>> > c = groupingBy(String::length) 3 4 5 one, two, six, ten four, five, nine three, seven, eight   
  • 83. one, two, three, four, five, six, seven, eight, nine, ten Collector<String, ?, Map<Integer, List<String>> > c = groupingBy( String::length, ? ) 3 4 5 one, two, six, ten four, five, nine three, seven, eight   
  • 84. one, two, three, four, five, six, seven, eight, nine, ten Collector<String, ?, Map<Integer, List<String>> > c = groupingBy( String::length, Collector<String, ?, > ) 3 4 5 one, two, six, ten four, five, nine three, seven, eight   
  • 85. one, two, three, four, five, six, seven, eight, nine, ten Collector<String, ?, Map<Integer, Value>> c = groupingBy( String::length, Collector<String, ?, Value> ) counting() : Collector<T, ?, Long> 3 4 5 4L 3L 3L   
  • 87. Intermediate Collectors Back to the mapping collector This collector takes a downstream collector stream.collect(mapping(function, downstream));
  • 88. Intermediate Collectors The mapping Collector provides an intermediate operation stream.collect(mapping(function, downstream));
  • 89. Intermediate Collectors The mapping Collector provides an intermediate operation Why is it interesting? To create downstream collectors! So what about integrating all our stream processing as a collector? stream.collect(mapping(function, downstream));
  • 90. Intermediate Collectors If collectors can map, why would’nt they filter, or flatMap? …in fact they can in 9 ☺
  • 91. Intermediate Collectors The mapping Collector provides an intermediate operation We have a Stream<T> So predicate is a Predicate<T> Downstream is a Collector<T, ?, R> stream.collect(mapping(function, downstream)); stream.collect(filtering(predicate, downstream));
  • 92. Intermediate Collectors The mapping Collector provides an intermediate operation We have a Stream<T> So flatMapper is a Function<T, Stream<TT>> And downstream is a Collector<TT, ?, R> stream.collect(mapping(function, downstream)); stream.collect(flatMapping(flatMapper, downstream));
  • 94. Characteristics Three characteristics for the collectors: - IDENTITY_FINISH: the finisher is the identity function - UNORDERED: the collector does not preserve the order of the elements - CONCURRENT: the collector is thread safe
  • 95. Handling Empty Optionals Two things: - Make an Optional a Stream - Remove the empty Streams with flatMap Map<K, Optional<V>> // with empty Optionals... -> Map<K, Steam<V>> // with empty Streams -> Stream<Map.Entry<K, V>> // the empty are gone -> Map<K, V> // using a toMap
  • 96. Joins 1) The authors that published the most together 2) The authors that published the most together in a year StreamsUtils to the rescue!
  • 97. Gent & Walsh, Beyond NP: The QSAT Phase Transition Gent & Hoos & Prosser & Walsh, Morphing: Combining… Gent, Hoos, Prosser, Walsh Gent, Walsh {Gent, Walsh} {Gent, Hoos} {Gent, Prosser} {Gent, Walsh} {Hoos, Prosser} {Hoos, Walsh} {Prosser, Walsh} flatMap()
  • 99. Application What is interesting in modeling a processing as a collector? We can reuse this collector as a downstream collector for other processings
  • 100. What About Readability? Creating composable Collectors
  • 102. Dealing with Issues The main issue is the empty stream A whole stream may have elements But when we build an histogram, a given substream may become empty…
  • 104. API Collector A very rich API indeed Quite complex… One needs to have a very precise idea of the data processing pipeline Can be extended!
  • 105. API Collector A collector can model a whole processing Once it is written, it can be passed as a downstream to another processing pipeline Can be made composable to improve readability https://github.com/JosePaumard
  • 106. Thank you for your attention!