navigating the stream api - jfokusfocussed on exploring the api from the developer’s viewpoint,...
TRANSCRIPT
![Page 1: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/1.jpg)
Navigating the Stream API
Maurice NaftalinMorningside Light Ltd
Code font??Colour-emphasise example devt
Thank JFokus, thank youHow is this talk different from all other lambda talks? — not motivational, sharply focussed on exploring the API from the developer’s viewpoint, test at the end.
![Page 2: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/2.jpg)
Developer, designer, architect, teacher, learner, writer
Maurice Naftalin
Co-authorCurrent Projects
www.lambdafaq.org
2
Another way of saying that I don’t have a real job8th April 2014, 208 pages
![Page 3: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/3.jpg)
• Fundamentals
• API Overview
• Stream Operations
• Let’s Push the Boat Out!
3
Navigating the Stream API
Lame jokes, test but it’s of me
![Page 4: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/4.jpg)
Streams – Why?
• Intention: replace loops for aggregate operations
• more concise, more readable, composable operations, parallelizable
Set<City> shortCities = new HashSet<>();
for (Person p : people) { City c = p.getCity(); if (c.getName().length() < 4 ) { shortCities.add(c); }}
instead of writing this:
4
Do code before 2nd bulletI said not motivational, I’m assuming you have been to Brian’s talks, Kool-AidParallel version would be much longer - provide it?SELECT P.NAME FROM PERSON P WHERE LENGTH(P.NAME) < 4
![Page 5: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/5.jpg)
Streams – Why?
• Intention: replace loops for aggregate operations
• more concise, more readable, composable operations, parallelizable
Set<City> shortCities = new HashSet<>();
for (Person p : people) { City c = p.getCity(); if (c.getName().length() < 4 ) { shortCities.add(c); }}
instead of writing this:
Set<City> shortCities = people.stream() .map(Person::getCity) .filter(c -> c.getName().length() < 4) .collect(toSet());
5
we’re going to write this:
Mention method reference
![Page 6: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/6.jpg)
Streams – Why?
• Intention: replace loops for aggregate operations
• more concise, more readable, composable operations, parallelizable
Set<City> shortCities = new HashSet<>();
for (Person p : people) { City c = p.getCity(); if (c.getName().length() < 4 ) { shortCities.add(c); }}
instead of writing this:
Set<City> shortCities = people.parallelStream() .map(Person::getCity) .filter(c -> c.getName().length() < 4) .collect(toSet());
6
we’re going to write this:
I said not motivational, I’m assuming you have been to Brian’s talks, Kool-AidParallel version would be much longer - provide it?Generate SQL, like LINQ?
![Page 7: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/7.jpg)
On The Other Hand...
Instead of writing
Map<City,List<Name>> namesByCity = new HashMap<>();
for (Person p : people) { City c = p.getCity(); if (! namesByCity.containsKey(c)) { namesByCity.put(c, new ArrayList<>()); } namesByCity.get(c).add(p.getName());}
7
![Page 8: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/8.jpg)
On The Other Hand...
Instead of writingMap<City,List<Name>> namesByCity = new HashMap<>();
for (Person p : people) { City c = p.getCity(); if (! namesByCity.containsKey(c)) { namesByCity.put(c, new ArrayList<>()); } namesByCity.get(c).add(p.getName());}
Map<City, List<Name>> namesByCity = people.stream() .collect(groupingBy(Person::getCity, mapping(Person::getName,Collectors.toList())));
Does this mean that streams are hard to use?8
We’re going to write
No, it means that you’ve come to the right talk
![Page 9: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/9.jpg)
Streams
Sequence of values
• Not a collection — may be partially evaluated or exhausted
• Like an iterator, yielding elements for processing
• Not like an iterator, not associated with any storage mechanism
• Sources: collections, arrays, generators, filesystems, strings, IO buffers,...
• Can be
- parallel
- infinite
• Primitive specialisations: IntStream, LongStream, DoubleStream
Like Unix streams
![Page 10: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/10.jpg)
Navigating the Stream API
• Fundamentals
• API Overview
• Stream Operations
• Let’s Push the Boat Out!
![Page 11: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/11.jpg)
The Life of a Pipeline
• Born at a source
• Successive intermediate operations• often use lambdas/method references to transform (or drop) values
• operation itself returns a new stream that will carry transformed values
• Dies at a terminal operation• terminal operations “pull” values down the pipeline
11
![Page 12: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/12.jpg)
Terminal
Stateless Stateful
filtermapflatMappeek
distinctlimitsubstream sorted
Reduction
reducemin,maxcount
SearchanyMatch allMatchfindAnyfindFirst
forEachforEachOrdered
MutableReductioncollecttoArray
Stream Operations – the Map
SM: sorted different because must collect all values before proceeding
therefore fails completely on an infinite
Intermediate
![Page 13: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/13.jpg)
• Fundamentals
• API Overview
• Stream Operations
• Intermediate Stateless Operations
• Let’s Push the Boat Out!
Navigating the Stream API
![Page 14: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/14.jpg)
Intermediate Operations
• return new Streams
• lazy: they create a new Stream, not new elements
Stream<City> cities = people.stream() .map(p -> p.getCity());
14
![Page 15: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/15.jpg)
x0 y0x1 y1x2 x3
Visualizing Stream Operations
darken the streams!
SM: explain why flying off (and make flying off work!)
For visual learnersBut note: principle of processing mode equality
![Page 16: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/16.jpg)
x2
Visualizing Stream Operations
x0
y0
x1y1
x3y2
y3
16
x0
x1
x2
x3
This neat picture is not realistic!No guarantees on ordering beyond what’s required to maintain the semantics of the the operation.
![Page 17: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/17.jpg)
Interference
x0
y0
x1
x2
y3
17
y1
✗
x0
x1y1
x3x3
API documentation says don’t do this, ever. In fact, no-one should fritz with the source of an executing pipeline, unless it’s concurrent.Prime directive
![Page 18: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/18.jpg)
name returns interface used l signaturefilter Stream<T> Predicate<T> T ➞ booleanmap Stream<U> Function<T,U> T ➞ UflatMap Stream<R> Function<T,Stream<R>> T ➞ Stream<R>peek Stream<T> Consumer<T> T ➞ void
Stateless Intermediate Operations
18
mapToInt IntStream ToIntFunction<T> T ➞ intmapToLong LongStream ToLongFunction<T> T ➞ longmapToDouble DoubleStream ToDoubleFunction<T> T ➞ double
only the type bounds, here and everywhere in the talkfilter takes Predicate<? super T> etc
![Page 19: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/19.jpg)
✖
filter(s -‐> s.length() < 4)
Stream<String>
Predicate<String>
“bill”
Stream<String>
filter()
19
“jim”
✔
“amy”
![Page 20: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/20.jpg)
map()
map(Person::getCity)
Stream<Person> Stream<City>
Function<Person,City>
Londonbill Athensamy
![Page 21: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/21.jpg)
flatMapToInt()
Stream<String>
Func>on<String,IntStream>
IntStream
'a' 'm' 'y'
flatMapToInt(String::chars)
It’s ok to hold the input value inside the blue box temporarily — it’s never mutated, so just a convenient visual notation
![Page 22: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/22.jpg)
Navigating the Stream API
• Fundamentals
• API Overview
• Stream Operations
• Intermediate Stateful Operations
• Let’s Push the Boat Out!
![Page 23: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/23.jpg)
name returns type used l signature
limit Stream<T> long
substream Stream<T> (long, long)
sorted Stream<T> Comparator<T> (T, T) ➞ int
distinct Stream<T>
Stateful Intermediate Operations
![Page 24: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/24.jpg)
24
x2
x0
x1
x3
x0
x1
x2
x3
Visualizing Stream Operations
y0
y1
y2
y3
Stateless
Stateful
z0
z0
z1 z2 z3
Not all of them, of course
![Page 25: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/25.jpg)
25
Visualizing Stream Operations
3
1
4
2
sorted()
Sorted is always a barrier Not all of them, of course
![Page 26: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/26.jpg)
Navigating the Stream API
• Fundamentals
• API Overview
• Stream Operations
• Terminal Operations
• Let’s Push the Boat Out!
![Page 27: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/27.jpg)
Terminal Operations
• return non-Stream values
• typically eager: they force evaluation of their stream
Set<City> cities = people.stream() .map(p -> p.getCity()) .collect(toSet());
27
Result is a non-stream value
![Page 28: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/28.jpg)
OptionalInt
Reduction by Accumulation
IntStream
IntBinaryOperator
24
28
(a,b) -> a* b32
6
4
reduce((a,b) -‐> a*b)
Note exhaustion of input streamTraditional FP way of thinking about reductionBUT: every reduction must be doable in parallel
![Page 29: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/29.jpg)
Reduction by Merging
29
z0
reduce((a,b) -> a*b) 2
4
1
36
24
With larger set, lots of parallel working, (finally must be serialised, of course)There must be a symmetric variant of any reduction
![Page 30: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/30.jpg)
Reduction Operations
name returns interface used l signaturereduce Optional<T> BinaryOperator<T> (T, T) ➞ Tmin, max Optional<T> Comparator<T> (T, T) ➞ int
count long
30
another overload of reduce also takes an accumulator function, butthere is no overload with only an
accumulator function
primitive versions have others eg sum and statistics
![Page 31: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/31.jpg)
Mutable Reductions
• What is a collector?
• aggregates values of type T into a container, of type R
• A is an intermediate type, used to accumulate T values before they are “finished” into an R
• for example, StringBuilder is used an intermediate type when Strings are joined
31
public <R,A> R collect(Collector<T,A,R>)
Mutable reductions collect the values of a stream into a “container”
also toArrayA is often an implementation detail
![Page 32: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/32.jpg)
Collecting
Stream<Person>
Collectors.toSet()
Set<Person>{ , , }
people.stream().collect(Collectors.toSet())
amybilljon
Collector<Person,?,Set<Person>>
Why is there an extra step? Either because there is a finishing function (not shown) or because there is going to be a subsseqent parallel merge (not shown)
![Page 33: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/33.jpg)
Collectors
• Mostly you’ll use predefined Collectors
• Factory methods in the java.util.stream.Collectors
• counting
• summing/averaging/summarizing (for each of int, long, double)
• joining (for Strings)
• toList/Map/Set
• reducing
• groupingBy(x3)
• mapping33
Think of the container in each case
![Page 34: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/34.jpg)
Collectors.groupingBy(Function classifier)
3435
Map<City,List<Person>> peopleByCity = people.stream().collect(Collectors.groupingBy(Person::getCity));
Uses the classifier function to make a classification mapping
Persons are classified according to the City that classifier gives them;same-classified Persons are put into a List
For example, use Person.getCity() to make a Map<City,List<Person>>
List is the default
![Page 35: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/35.jpg)
groupingBy(Function classifier)
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens [ ]
35
[ , ]
bill
[ ]
amyjon
London
Collector<Person,?,Map<City,List<Person>>
Classifier
Person→City
Justify generics in Collector (SM: this is hard enough to justify separate treatment)
What if you don’t want to put them into a List, though?
![Page 36: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/36.jpg)
3635
Map<City,Set<Person>> peopleByCity = people.stream().collect(Collectors.groupingBy(Person::getCity,toSet()));
Uses the classifier function to make a classification mapping
Persons are classified according to the City that classifier gives them;same-classified Persons are put into
a container defined by the downstream collector
For example, use Person.getCity() to make a Map<City,Set<Person>>
groupingBy(Function classifier,Collector downstream))
![Page 37: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/37.jpg)
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()Map<City,Set<Person>>
bill
jon
amy
London
Athens { }
amy
37
Classifier
Person→City
Stream<Person>
DownstreamCollector
—toSet()
{ , }
billjon
Each T goes to the collector for its classification key
![Page 38: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/38.jpg)
mapping(Function mapper,Collector downstream))
38
Set<City> inhabited = people.stream().collect(Collectors.mapping(Person::getCity,toSet()))
Adapts a Collector accepting elements of one type to one accepting elements of another
by applying a mapping function to each input element before accumulation by the downstream collector.
API documentation
![Page 39: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/39.jpg)
mapping(Function mapper,Collector downstream))
LondonStream<Person>
mapping()
bill
jon
amy
{ , }
amyjonbill
39
AthensAthens
LondonLondonMapper
Person→City
DownstreamCollector
—toSet()
Stream<City>
Set<City>
Question to BG: Why no overload with default collector?
SM: Stupid example, you would just use an upstream map(). Maybe leave, but explain useful as downstream collector, see examples at end.
![Page 40: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/40.jpg)
Navigating the Stream API
• Fundamentals
• API Overview
• Stream Operations
• Let’s Push the Boat Out!
![Page 41: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/41.jpg)
From a stream of Person, compute
• List of the adults
• Set of ages of the adults
• Listing of people by age
• Population by age
• Names by age
• Most popular age
• Bonus: Most popular ages
Some Problems
First 5 doable from presentation, 6th needs something moreBonus is a “problem for the reader”Mavens: help out, but only if...
![Page 42: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/42.jpg)
List<Person> adults = people.stream() .filter( ) .collect(toList());
List of adults (age > 21)
Problem 1
✘18
p -‐> p.getAge() > 18
Assuming static imports of Collectors factory methodsBuilding next problems up from previous ones
![Page 43: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/43.jpg)
Problem 2
Set<Integer> adultAges = people.stream() .filter(p -‐> p.getAge() > 21) .collect(toList());
Set of ages of the adults
![Page 44: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/44.jpg)
Problem 2
Set<Integer> adultAges = people.stream() .filter(p -‐> p.getAge() > 21)
.collect(toList());
Set of ages of the adults
SM: Fade or strikethrough the old code
![Page 45: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/45.jpg)
Set of ages of the adults
Problem 2
Set<Integer> adultAges = people.stream() .filter(p -‐> p.getAge() > 21)
.map(Person::getAge) .collect(toList());
![Page 46: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/46.jpg)
Problem 2
Set<Integer> adultAges = people.stream() .filter(p -‐> p.getAge() > 21)
.map(Person::getAge) .collect(toSet());
Set of ages of the adults
![Page 47: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/47.jpg)
People by Age
Problem 3
Map<Integer,List<Person>> peopleByAge = people.stream() .filter(p -> p.getAge() > 21)
.map(Person::getAge) .collect(toSet());
SM: overall comment — introduce Collectors properly
Can we keep any of this? (No)
![Page 48: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/48.jpg)
People by Age
Problem 3
Map<Integer,List<Person>> peopleByAge = people.stream() .filter(p -> p.getAge() > 21)
.map(Person::getAge) .collect(groupingBy( ?? ));
![Page 49: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/49.jpg)
People by Age
Problem 3
Map<Integer,List<Person>> peopleByAge = people.stream() .filter(p -> p.getAge() > 21)
.map(Person::getAge) .collect(groupingBy(Person::getAge));
![Page 50: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/50.jpg)
People by Age
Problem 3
Map<Integer,List<Person>> peopleByAge = people.stream() .collect(groupingBy(Person::getAge));
![Page 51: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/51.jpg)
Population by Age
Problem 4
Map<Integer,Long> populationbyAge = people.stream() .collect(groupingBy(Person::getAge));
![Page 52: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/52.jpg)
Population by Age
Problem 4
Map<Integer,Long> populationByAge = people.stream() .collect(groupingBy(Person::getAge,
?? ));
![Page 53: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/53.jpg)
Population by Age
Problem 4
Map<Integer,Long> populationByAge = people.stream() .collect(groupingBy(Person::getAge,
counting()));
![Page 54: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/54.jpg)
Names by Age
Problem 5
Map<Integer,List<Name>> namesByAge = people.stream() .collect(groupingBy(Person::getAge,
counting()));
![Page 55: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/55.jpg)
Names by Age
Problem 5
Map<Integer,List<Name>> namesByAge = people.stream() .collect(groupingBy(Person::getAge,
?? ));
![Page 56: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/56.jpg)
Names by Age
Problem 5
Map<Integer,List<Name>> namesByAge = people.stream() .collect(groupingBy(Person::getAge,
mapping( ?? , ?? )));
![Page 57: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/57.jpg)
Names by Age
Problem 5
Map<Integer,List<Name>> namesByAge = people.stream() .collect(groupingBy(Person::getAge,
mapping(Person::getName,toList())));
![Page 58: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/58.jpg)
Problem 6
Most Popular Age
Optional<Integer> modalAge = populationByAge .entrySet() .stream() .max(Entry.comparingByValue()) .map(Entry::getKey);
populationByAge is Map<Integer,Long>
![Page 59: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/59.jpg)
Optional<Set<Integer>> modalAges = populationByAge .entrySet()
.stream() .collect(groupingBy(Entry::getValue, mapping(Entry::getKey, toSet()))) .entrySet() .stream() .max(Entry.comparingByKey()) .map(Entry::getValue);
Problem 7
Most Popular Ages
![Page 60: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/60.jpg)
• Collections processing with streams looks very different
• But the payoff is huge!
• Need to learn to think differently – but it’s not that hard!
Summary
If you’re invested in Java, this is a great developmentSpeaking as a person who’s written on the two big language changes Java 5 and Java 8
![Page 61: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/61.jpg)
• Brian Goetz talk @ JavaOne 2014 (parleys.com) http://goo.gl/OEjk1h
• State of the Lambda, Libraries Edition
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-libraries-final.html
• java.util.stream API package documentation
• Lambda FAQ (http://lambdafaq.org) – collections material coming real soon!
• Out now: Functional Programming in Java, Venkat Subramaniam
• Out soon—honestly!
• Java 8 Lambdas in Action, Raoul Urma, Mario Fusco, Alan Mycroft (Mannning, early access)
• Java 8 Lambdas: Pragmatic Functional Programming, Richard Warburton
• Mastering Lambdas: Java Programming in a Multicore World, Maurice Naftalin
Resources
![Page 62: Navigating the Stream API - Jfokusfocussed on exploring the API from the developer’s viewpoint, test at the end. Developer, designer, architect, teacher, learner, writer ... •often](https://reader033.vdocuments.mx/reader033/viewer/2022052802/5f1ac8e5f6160f4ed876bd54/html5/thumbnails/62.jpg)
Navigating the Stream API
Questions?