SlideShare a Scribd company logo
1 of 157
Download to read offline
Journey’s End
Collection and Reduction in the Stream API
JavaOne, October 2015
Developer, designer, architect, teacher, learner, writer
Maurice Naftalin
Co-author
Current Projects
www.lambdafaq.org
2
• Why collectors?
• Using the predefined collectors
• Intermission!
• Worked problems
• Writing your own
Journey’s End – Agenda
Journey’s End, JavaOne, October 2015
Example Domain
city: City
name: String
age: int
Person
Person amy = new Person(Athens, "Amy", 21);

...
List<Person> people = Arrays.asList(jon, amy, bill);

Journey’s End, JavaOne, October 2015
Collectors: Journey’s End for a Stream
The Life of a Stream Element
• Born (at a spliterator)
• Transformed (by intermediate operations)
• Collected (by a terminal operation)
Journey’s End, JavaOne, October 2015
Collectors: Journey’s End for a Stream
The Life of a Stream Element
• Born (at a spliterator)
• Transformed (by intermediate operations)
• Collected (by a terminal operation)
Journey’s End, JavaOne, October 2015
Collectors: Journey’s End for a Stream
The Life of a Stream Element
• Born (at a spliterator)
• Transformed (by intermediate operations)
• Collected (by a terminal operation)
Journey’s End, JavaOne, October 2015
Collectors: Journey’s End for a Stream
The Life of a Stream Element
• Born (at a spliterator)
• Transformed (by intermediate operations)
• Collected (by a terminal operation)
Journey’s End, JavaOne, October 2015
Collectors: Journey’s End for a Stream
?
The Life of a Stream Element
• Born (at a spliterator)
• Transformed (by intermediate operations)
• Collected (by a terminal operation)
Journey’s End, JavaOne, October 2015
Terminal Operations
– Search operations
– Side-effecting operations
– Reductions

Journey’s End, JavaOne, October 2015
Search Operations
Search operations -
• allMatch, anyMatch
• findAny, findFirst
boolean allAdults =
people.stream()

.allMatch(p -> p.getAge() >= 21);

Journey’s End, JavaOne, October 2015
Side-effecting Operations
Side-effecting operations
• forEach, forEachOrdered



people.stream()

.forEach(System.out::println);
• So could we calculate total ages like this?



int sum = 0;

people.stream()

.mapToInt(Person::getAge)

.forEach(a -> { sum += a });
people.stream()

.forEach(System.out::println);

int sum = 0;

people.stream()

.mapToInt(Person::getAge)

.forEach(a -> { sum += a; });

Journey’s End, JavaOne, October 2015
Side-effecting Operations
Side-effecting operations
• forEach, forEachOrdered



people.stream()

.forEach(System.out::println);
• So could we calculate total ages like this?



int sum = 0;

people.stream()

.mapToInt(Person::getAge)

.forEach(a -> { sum += a });
people.stream()

.forEach(System.out::println);

int sum = 0;

people.stream()

.mapToInt(Person::getAge)

.forEach(a -> { sum += a; });

Don’t do this!
Journey’s End, JavaOne, October 2015
• Using an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
int sum = 0;
for (int i = 0 ; i < vals.length ; i++) {
sum += vals[i];
}

Journey’s End, JavaOne, October 2015
• Using an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
int sum = 0;
for (int i = 0 ; i < vals.length ; i++) {
sum += vals[i];
}

0 1 2 3
+
+
Journey’s End, JavaOne, October 2015
• Using an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
int sum = 0;
for (int i = 0 ; i < vals.length ; i++) {
sum += vals[i];
}

0 1 2 3
+
+
+
Journey’s End, JavaOne, October 2015
• Avoiding an accumulator:
Reduction – Why?
Journey’s End, JavaOne, October 2015
• Avoiding an accumulator:
Reduction – Why?
Journey’s End, JavaOne, October 2015
• Avoiding an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
OptionalInt sum = Arrays.stream(vals)
.reduce((a,b) -> a + b);

+ +
+
1 2 30
Journey’s End, JavaOne, October 2015
• Avoiding an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
OptionalInt sum = Arrays.stream(vals)
.reduce((a,b) -> a + b);

+ +
+
1 2 30
+
+
+
Journey’s End, JavaOne, October 2015
• Avoiding an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
OptionalInt sum = Arrays.stream(vals)
.reduce((a,b) -> a + b);

BinaryOperator must be associative!
+ +
+
1 2 30
+
+
+
Journey’s End, JavaOne, October 2015
• Avoiding an accumulator:
Reduction – Why?
int[] vals = new int[100];
Arrays.setAll(vals, i -> i);
OptionalInt sum = Arrays.stream(vals)
.reduce((a,b) -> a + b);

BinaryOperator must be associative!
a + (b + c) = (a + b) + c
+ +
+
1 2 30
+
+
+
Journey’s End, JavaOne, October 2015
Why Reduction?
0 1 2 3 4 5 6 7
+ +
+
+
+
+
+
Journey’s End, JavaOne, October 2015
Why Reduction?
0 1 2 3 4 5 6 7
+ +
+
+
+
+
+
Journey’s End, JavaOne, October 2015
Why Reduction?
0 1 2 3 4 5 6 7
+ +
+
+
+
+
+
Intermediate operations
Journey’s End, JavaOne, October 2015
Reduction on ImmutableValues
Reduction works on immutable values too
BigDecimal[] vals = new BigDecimal[100];
Arrays.setAll(vals, i -> new BigDecimal(i));
Optional<BigDecimal> sum = Arrays.stream(vals)
.reduce(BigDecimal::add);

Journey’s End, JavaOne, October 2015
Reduction on ImmutableValues
Reduction works on immutable values too
BigDecimal[] vals = new BigDecimal[100];
Arrays.setAll(vals, i -> new BigDecimal(i));
Optional<BigDecimal> sum = Arrays.stream(vals)
.reduce(BigDecimal::add);

Journey’s End, JavaOne, October 2015
Reduction to Collections?
Journey’s End, JavaOne, October 2015
Reduction to Collections?
This also works with collections – sort of ...
• for each element, client code creates a new empty
collection and adds the single element to it
• combines collections using addAll
Journey’s End, JavaOne, October 2015
Reduction to Collections?
This also works with collections – sort of ...
• for each element, client code creates a new empty
collection and adds the single element to it
• combines collections using addAll
We can do better!
Journey’s End, JavaOne, October 2015
Reduction over an Identity
BigDecimal[] vals = new BigDecimal[100];
Arrays.setAll(vals, i -> new BigDecimal(i));
BigDecimal sum = Arrays.stream(vals)
.reduce(BigDecimal.ZERO,BigDecimal::add);

Journey’s End, JavaOne, October 2015
Reduction over an Identity
BigDecimal[] vals = new BigDecimal[100];
Arrays.setAll(vals, i -> new BigDecimal(i));
BigDecimal sum = Arrays.stream(vals)
.reduce(BigDecimal.ZERO,BigDecimal::add);

Works for immutable objects:
Journey’s End, JavaOne, October 2015
Reduction over an Identity
+
+
+
0 1 2 3
+
+
+
0
4 5 6 7
0
++
+
Journey’s End, JavaOne, October 2015
Reduction to Collections?
Journey’s End, JavaOne, October 2015
Reduction to Collections?
Reduction over an identity doesn’t work with
collections at all
• reduction reuses the identity element
Journey’s End, JavaOne, October 2015
Reduction to Collections?
Reduction over an identity doesn’t work with
collections at all
• reduction reuses the identity element
We’ve got to do better!
Journey’s End, JavaOne, October 2015
The Answer – Collectors
a
a
a
e0 e1 e2 e3
a
a
a
e4 e5 e6 e7
aa
c
a: accumulator
c: combiner
Journey’s End, JavaOne, October 2015
The Answer – Collectors
a
a
a
e0 e1 e2 e3
a
a
a
() -> []
e4 e5 e6 e7
aa
c
a: accumulator
c: combiner
() -> []
Journey’s End, JavaOne, October 2015
Collectors
So to define a collector, you need to provide
• Supplier
• Accumulator
• Combiner
That sounds really hard!
Good then that we don’t have to do it
• – very often
Journey’s End, JavaOne, October 2015
Collectors API
Factory methods in the Collectors class.They
produce standalone collectors, accumulating to:
• framework-supplied containers;
• custom collections;
• classification maps.
• Why collectors?
• Using the predefined collectors
• Intermission!
• Worked problems
• Writing your own
Journey’s End – Agenda
Journey’s End, JavaOne, October 2015
Predefined Standalone Collectors – from factory
methods in Collections class
• toList(), toSet(), toMap(), joining()
• toMap(), toCollection()
groupingBy(), partitioningBy(),
groupingByConcurrent()
Using the Predefined Collectors
Journey’s End, JavaOne, October 2015
Predefined Standalone Collectors – from factory
methods in Collections class
• toList(), toSet(), toMap(), joining()
• toMap(), toCollection()
groupingBy(), partitioningBy(),
groupingByConcurrent()
Using the Predefined Collectors
framework provides
the Supplier
Journey’s End, JavaOne, October 2015
Predefined Standalone Collectors – from factory
methods in Collections class
• toList(), toSet(), toMap(), joining()
• toMap(), toCollection()
groupingBy(), partitioningBy(),
groupingByConcurrent()
Using the Predefined Collectors
user provides
the Supplier
framework provides
the Supplier
Journey’s End, JavaOne, October 2015
Predefined Standalone Collectors – from factory
methods in Collections class
• toList(), toSet(), toMap(), joining()
• toMap(), toCollection()
groupingBy(), partitioningBy(),
groupingByConcurrent()
Using the Predefined Collectors
user provides
the Supplier
framework provides
the Supplier
produce a 

classification map
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Collectors.toSet()
people.stream().collect(Collectors.toSet())
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
bill
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
bill
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
bill
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
bill
jon
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
bill
jon
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
amy
bill
jon
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Stream<Person>
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
amy
bill
jon
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Collectors.toSet()
Set<Person>
people.stream().collect(Collectors.toSet())
amy
bill
jon
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
Simple Collector – toSet()
Collectors.toSet()
Set<Person>
{ , , }
people.stream().collect(Collectors.toSet())
amybilljon
Collector<Person,?,Set<Person>>
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
people.stream().collect(
Collectors.toMap(
Person::getCity,

Person::getName))
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
Collector<Person,?,Map<City,String>
people.stream().collect(toMap(Person::getCity,Person::getName))
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
Collector<Person,?,Map<City,String>
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
bill
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
bill
Person::getCity
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
London
bill
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
London
bill Person::getName
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
London “Bill”
bill Person::getName
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
London “Bill”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
amy
London “Bill”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
Athens
amy
London “Bill”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
London “Bill”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
jon
London “Bill”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
London “Bill”
Tulsa “Jon”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
toMap() Map<City,String>
“Amy”Athens
London “Bill”
Tulsa “Jon”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
toMap() Map<City,String>
“Amy”Athens
London “Bill”
Tulsa “Jon”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
jon
London “Bill”
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
jon
London “Bill”
Athens
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
jon
London
IllegalStateException
“Bill”
Athens
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
people.stream().collect(
Collectors.toMap(
Person::getCity,

Person::getName,
(a,b) -> a.concat(b)))
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
Stream<Person>
toMap() Map<City,String>
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
London “Bill”
Athens
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
London “Bill”
Athens
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
London “Bill”
“Jon”
Athens
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
Stream<Person>
toMap() Map<City,String>
“Amy”Athens
London “Bill”
“Jon”
(a,b) -> a.concat(b)
Athens
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
Stream<Person>
toMap() Map<City,String>
Athens
London “Bill”
(a,b) -> a.concat(b)
“AmyJon”
Athens
Journey’s End, JavaOne, October 2015
Collectors API
Factory methods in the Collectors class.They
produce standalone collectors, accumulating to:
• framework-supplied containers;
• custom collections;
• classification maps.
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction)
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction,
Supplier<M> mapFactory)
people.stream().collect(
Collectors.toMap(
Person::getCity,

Person::getName,
(a,b) -> a.concat(b),

TreeMap::new))
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction,
Supplier<M> mapFactory)
Stream<Person>
toMap() Map<City,String>
Journey’s End, JavaOne, October 2015
toMap(Function<T,K> keyMapper,
Function<T,U> valueMapper
BinaryOperator<U> mergeFunction,
Supplier<M> mapFactory)
Stream<Person>
toMap() Map<City,String>
Journey’s End, JavaOne, October 2015
Collecting to Custom Collections
<C extends Collection<T>>
NavigableSet<String> sortedNames = people.stream()
.map(Person::getName)

.collect(toCollection(TreeSet::new));
Journey’s End, JavaOne, October 2015
Collecting to Custom Collections
toCollection(Supplier<C> collectionFactory)
<C extends Collection<T>>
NavigableSet<String> sortedNames = people.stream()
.map(Person::getName)

.collect(toCollection(TreeSet::new));
Journey’s End, JavaOne, October 2015
Collectors API
Factory methods in the Collectors class.They
produce standalone collectors, accumulating to:
• framework-supplied containers;
• custom collections;
• classification maps.
Journey’s End, JavaOne, October 2015
Collecting to Classification Maps
groupingBy
• simple
• with downstream
• with downstream and map factory
partitioningBy
Journey’s End, JavaOne, October 2015
groupingBy(Function<T,K> classifier)
Uses the classifier function to make a classification mapping
Like toMap(), except that the values placed in the map are lists of the
elements, one List corresponding to each classification key:
For example, use Person.getCity() to make a Map<City,List<Person>>
Map<City,List<Person>> peopleByCity = people.stream().

collect(Collectors.groupingBy(Person::getCity));
Journey’s End, JavaOne, October 2015
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens
London
Collector<Person,?,Map<City,List<Person>
groupingBy(Function<Person,City>)
Classifier
Person→City
Journey’s End, JavaOne, October 2015
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens
London
groupingBy(Function<Person,City>)
Journey’s End, JavaOne, October 2015
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens
bill London
groupingBy(Function<Person,City>)
Journey’s End, JavaOne, October 2015
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens
billLondon
groupingBy(Function<Person,City>)
[ ]
Journey’s End, JavaOne, October 2015
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens [ ]
bill
amy
London
groupingBy(Function<Person,City>)
[ ]
Journey’s End, JavaOne, October 2015
Stream<Person>
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens [ ]
[ , ]bill
amy
jonLondon
groupingBy(Function<Person,City>)
Journey’s End, JavaOne, October 2015
groupingBy() Map<City,List<Person>>
bill
jon
amy Athens [ ]
[ , ]bill
amy
jonLondon
groupingBy(Function<Person,City>)
Journey’s End, JavaOne, October 2015
groupingBy() Map<City,List<Person>>
bill
jon
amy
Athens [ ]
[ , ]bill
amy
jonLondon
groupingBy(Function<Person,City>)
Journey’s End, JavaOne, October 2015
groupingBy(Function<T,K> classifier)
Uses the classifier function to make a classification mapping
Like toMap(), except that the values placed in the map are lists of the
elements, one List corresponding to each classification key:
For example, use Person.getCity() to make a Map<City,List<Person>>
Map<City,List<Person>> peopleByCity = people.stream().

collect(Collectors.groupingBy(Person::getCity));
Journey’s End, JavaOne, October 2015
groupingBy(classifier, downstream)
Map<City,List<Person>> peopleByCity = people.stream().

collect(Collectors.groupingBy(Person::getCity,toSet()));
Uses the classifier function to make a classification mapping into a
container defined by a downstream Collector
Like toMap(), except that the values placed in the map are containers of
the elements, one container corresponding to each classification key:
For example, use Person.getCity() to make a Map<City,Set<Person>>
Map<City,Set<Person>> peopleByCity = people.stream().

collect(Collectors.groupingBy(Person::getCity,toSet()));
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens
Downstream
Collector
—
toSet()
Stream<Person
>
Classifier
Person→City
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athensamy
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens amy
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens amy
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens amy
jon bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
Stream<Person>
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens amy
jon
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens amy
jon
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens amy
jon
bill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens { }amy
{ , }jonbill
Journey’s End, JavaOne, October 2015
groupingBy(Function classifier,Collector downstream))
groupingBy()
Map<City,Set<Person>
bill
jon
amy
London
Athens { }amy
{ , }jonbill
Journey’s End, JavaOne, October 2015
mapping(Function mapper,Collector downstream))
Applies a mapping function to each input element before passing it
to the downstream collector.
Set<City> inhabited = people.stream()

.collect(mapping(Person::getCity,toSet()));
Map<City,String> namesByCity = people.stream()

.collect(groupingBy(Person::getCity,
mapping(Person::getName,joining()));
Animation example
Sensible example
mapping(Function mapper,Collector downstream))
LondonStream<Person>
mapping()
bill
jon
amy
41
Athens
Mapper
Person→City
Downstream
Collector
—
toSet()
Stream<City>
Set<City>
mapping(Function mapper,Collector downstream))
LondonStream<Person>
mapping()
bill
jon
amy
41
Athens
Set<City>
mapping(Function mapper,Collector downstream))
LondonStream<Person>
mapping()
bill
jon
amy
41
Athens
London
Set<City>
mapping(Function mapper,Collector downstream))
LondonStream<Person>
mapping()
bill
jon
amy
41
Athens
Athens
London
Set<City>
mapping(Function mapper,Collector downstream))
LondonStream<Person>
mapping()
bill
jon
amy
41
Athens
Athens
LondonLondon
Set<City>
mapping(Function mapper,Collector downstream))
London
mapping()
bill
jon
amy
41
Athens
Athens
LondonLondon
Set<City>
mapping(Function mapper,Collector downstream))
London
mapping()
bill
jon
amy
{ ,
}
41
Athens
Athens
London
Set<City>
mapping(Function mapper,Collector downstream))
London
mapping()
bill
jon
amy
{ ,
}
41
Athens
Athens
London
Set<City>
Dualling Convenience Reductions
• Collectors.counting()
• Collectors.maxBy
• Collectors.minBy
• Collectors.summarizingXXX
42
Journey’s End, JavaOne, October 2015
Concurrent Collection
Journey’s End, JavaOne, October 2015
Thread safety is guaranteed by the framework
• Even for non-threadsafe containers!
Concurrent Collection
Journey’s End, JavaOne, October 2015
Thread safety is guaranteed by the framework
• Even for non-threadsafe containers!
But at a price... So what if your container is already threadsafe?
• A concurrentMap implementation, for example?
Concurrent Collection
Journey’s End, JavaOne, October 2015
Thread safety is guaranteed by the framework
• Even for non-threadsafe containers!
But at a price... So what if your container is already threadsafe?
• A concurrentMap implementation, for example?
Concurrent Collection
Journey’s End, JavaOne, October 2015
Thread safety is guaranteed by the framework
• Even for non-threadsafe containers!
But at a price... So what if your container is already threadsafe?
• A concurrentMap implementation, for example?
Every overload of toMap() and groupingBy() has a dual
• toConcurrentMap(...)
• groupingByConcurrent(...)
Concurrent Collection
• Why collectors?
• Using the predefined collectors
• Intermission!
• Worked problems
• Writing your own
Journey’s End – Agenda
• Why collectors?
• Using the predefined collectors
• Intermission!
• Worked problems
• Writing your own
Journey’s End – Agenda
Journey’s End, JavaOne, October 2015
Writing a Collector
Why would you want to?
Journey’s End, JavaOne, October 2015
Writing a Collector
Why would you want to?
• accumulate to a container that doesn’t implement Collection
Journey’s End, JavaOne, October 2015
Writing a Collector
Why would you want to?
• accumulate to a container that doesn’t implement Collection
• share state between values being collected
Journey’s End, JavaOne, October 2015
Oprah’s Problem
Journey’s End, JavaOne, October 2015
Oprah’s Problem
How to find a book?
Journey’s End, JavaOne, October 2015
Oprah’s Problem
How to find a book?
336
640
144
624
Page count 239
640
384
1104
172
400
Journey’s End, JavaOne, October 2015
What Oprah Needs
New Earth 0
Poisonwood Bible 336
Night 976
A Fine Balance 1120
...
Cumulative
page counts
Supplier and Accumulator
“NE” 336 0 “PB” 640 336[ ],
]“NE” 336 0[
][
aNewEarth thePoisonwoodBible
accumulator
accumulator
Combiner
,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
Combiner
,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ],
,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
Combiner
combiner
,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ],
,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
Combiner
combiner
,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ],
,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
976
Combiner
combiner
,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ],
,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
976
Combiner
combiner
,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ],
,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
newEarth poisonwood night
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
newEarth poisonwood night
Page count
Start displacement
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[
newEarth poisonwood night
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[
newEarth poisonwood night
Map
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[
newEarth poisonwood night
Reduce
Map
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[
PartialResult::new
ArrayDeque::new
newEarth poisonwood night
Reduce
Map
Using Reduction Instead...
“New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ]
]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[
PartialResult::new
ArrayDeque::new
PartialResult::new
ArrayDeque::new
PartialResult::new
ArrayDeque::new
newEarth poisonwood night
Reduce
Journey’s End, JavaOne, October 2015
Performance of Collectors
Depends on the performance of accumulator and combiner
functions
• toList(), toSet(), toCollection – performance will probably be
dominated by accumulator, but remember that the framework will
need to manage multithread access to non-threadsafe containers
for the combine operation
toMap(), toConcurrentMap()
• map merging is slow. Resizing maps, especially concurrent maps, is
particularly expensive.Whenever possible, presize all data
structures, maps in particular.
Journey’s End, JavaOne, October 2015
Conclusion
Collectors
• generalisation of reduction
• allow a functional style while continuing to work with a
language based on mutation
• designed for composition
• flexible and powerful programming tool
• take a bit of getting used to! – but they’re worth it!
Journey’s End, JavaOne, October 2015
Questions?

More Related Content

What's hot

Swift and Kotlin Presentation
Swift and Kotlin PresentationSwift and Kotlin Presentation
Swift and Kotlin PresentationAndrzej Sitek
 
Writing Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using ScaldingWriting Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using ScaldingToni Cebrián
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Konrad Malawski
 
Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kros Huang
 
ACM DBPL Keynote: The Graph Traversal Machine and Language
ACM DBPL Keynote: The Graph Traversal Machine and LanguageACM DBPL Keynote: The Graph Traversal Machine and Language
ACM DBPL Keynote: The Graph Traversal Machine and LanguageMarko Rodriguez
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceKonrad Malawski
 
A dive into akka streams: from the basics to a real-world scenario
A dive into akka streams: from the basics to a real-world scenarioA dive into akka streams: from the basics to a real-world scenario
A dive into akka streams: from the basics to a real-world scenarioGioia Ballin
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinAndrey Breslav
 
Spark schema for free with David Szakallas
Spark schema for free with David SzakallasSpark schema for free with David Szakallas
Spark schema for free with David SzakallasDatabricks
 
Streaming all the things with akka streams
Streaming all the things with akka streams   Streaming all the things with akka streams
Streaming all the things with akka streams Johan Andrén
 
Unit testing of spark applications
Unit testing of spark applicationsUnit testing of spark applications
Unit testing of spark applicationsKnoldus Inc.
 
Redesigning Common Lisp
Redesigning Common LispRedesigning Common Lisp
Redesigning Common Lispfukamachi
 
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Samir Bessalah
 
Streams: The Good, The Bad And The Ugly
Streams: The Good, The Bad And The UglyStreams: The Good, The Bad And The Ugly
Streams: The Good, The Bad And The UglySimon Ritter
 

What's hot (20)

Polyglot Grails
Polyglot GrailsPolyglot Grails
Polyglot Grails
 
Swift and Kotlin Presentation
Swift and Kotlin PresentationSwift and Kotlin Presentation
Swift and Kotlin Presentation
 
Writing Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using ScaldingWriting Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using Scalding
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014
 
Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹
 
Graphite
GraphiteGraphite
Graphite
 
ACM DBPL Keynote: The Graph Traversal Machine and Language
ACM DBPL Keynote: The Graph Traversal Machine and LanguageACM DBPL Keynote: The Graph Traversal Machine and Language
ACM DBPL Keynote: The Graph Traversal Machine and Language
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka Persistence
 
Intro to Akka Streams
Intro to Akka StreamsIntro to Akka Streams
Intro to Akka Streams
 
Kotlin on android
Kotlin on androidKotlin on android
Kotlin on android
 
A dive into akka streams: from the basics to a real-world scenario
A dive into akka streams: from the basics to a real-world scenarioA dive into akka streams: from the basics to a real-world scenario
A dive into akka streams: from the basics to a real-world scenario
 
R and C++
R and C++R and C++
R and C++
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 
Spark schema for free with David Szakallas
Spark schema for free with David SzakallasSpark schema for free with David Szakallas
Spark schema for free with David Szakallas
 
Streaming all the things with akka streams
Streaming all the things with akka streams   Streaming all the things with akka streams
Streaming all the things with akka streams
 
Unit testing of spark applications
Unit testing of spark applicationsUnit testing of spark applications
Unit testing of spark applications
 
Redesigning Common Lisp
Redesigning Common LispRedesigning Common Lisp
Redesigning Common Lisp
 
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
 
Streams: The Good, The Bad And The Ugly
Streams: The Good, The Bad And The UglyStreams: The Good, The Bad And The Ugly
Streams: The Good, The Bad And The Ugly
 

Viewers also liked

QM-003-6 sigma
QM-003-6 sigmaQM-003-6 sigma
QM-003-6 sigmahandbook
 
Brand mantra of cupshup tea whitener
Brand mantra of cupshup tea whitenerBrand mantra of cupshup tea whitener
Brand mantra of cupshup tea whitenerBhagwan Das
 
Tutorial de Bases de Patentes versao 2016
Tutorial de Bases de Patentes versao 2016 Tutorial de Bases de Patentes versao 2016
Tutorial de Bases de Patentes versao 2016 Daniel Entorno
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroidSavvycom Savvycom
 
Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
Contextualizacion historica
Contextualizacion historicaContextualizacion historica
Contextualizacion historicaMrsilvam26
 
Managing gang of chaotic developers is complex at Agile Tour Riga 2012
Managing gang of chaotic developers is complex at Agile Tour Riga 2012Managing gang of chaotic developers is complex at Agile Tour Riga 2012
Managing gang of chaotic developers is complex at Agile Tour Riga 2012Piotr Burdylo
 
A Scalable I/O Manager for GHC
A Scalable I/O Manager for GHCA Scalable I/O Manager for GHC
A Scalable I/O Manager for GHCJohan Tibell
 
Agile Management 2013 - Nie tylko it
Agile Management 2013 - Nie tylko itAgile Management 2013 - Nie tylko it
Agile Management 2013 - Nie tylko itPiotr Burdylo
 
Présentation Kivy (et projets associés) à Pycon-fr 2013
Présentation Kivy (et projets associés) à Pycon-fr 2013Présentation Kivy (et projets associés) à Pycon-fr 2013
Présentation Kivy (et projets associés) à Pycon-fr 2013Gabriel Pettier
 
O'Reilly ETech Conference: Laszlo RIA
O'Reilly ETech Conference: Laszlo RIAO'Reilly ETech Conference: Laszlo RIA
O'Reilly ETech Conference: Laszlo RIAOliver Steele
 
Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009
Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009
Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009Alexandre Morgaut
 
Metasepi team meeting #6: "Snatch-driven development"
Metasepi team meeting #6: "Snatch-driven development"Metasepi team meeting #6: "Snatch-driven development"
Metasepi team meeting #6: "Snatch-driven development"Kiwamu Okabe
 

Viewers also liked (20)

Ancient rome world history
Ancient rome world historyAncient rome world history
Ancient rome world history
 
思考力
思考力思考力
思考力
 
O Mar
O MarO Mar
O Mar
 
QM-003-6 sigma
QM-003-6 sigmaQM-003-6 sigma
QM-003-6 sigma
 
Brand mantra of cupshup tea whitener
Brand mantra of cupshup tea whitenerBrand mantra of cupshup tea whitener
Brand mantra of cupshup tea whitener
 
Michel Vermote
Michel VermoteMichel Vermote
Michel Vermote
 
De uil van minerva (ucll)
De uil van minerva (ucll)De uil van minerva (ucll)
De uil van minerva (ucll)
 
vrijBOEKpark
vrijBOEKparkvrijBOEKpark
vrijBOEKpark
 
Tutorial de Bases de Patentes versao 2016
Tutorial de Bases de Patentes versao 2016 Tutorial de Bases de Patentes versao 2016
Tutorial de Bases de Patentes versao 2016
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroid
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Contextualizacion historica
Contextualizacion historicaContextualizacion historica
Contextualizacion historica
 
Managing gang of chaotic developers is complex at Agile Tour Riga 2012
Managing gang of chaotic developers is complex at Agile Tour Riga 2012Managing gang of chaotic developers is complex at Agile Tour Riga 2012
Managing gang of chaotic developers is complex at Agile Tour Riga 2012
 
A Scalable I/O Manager for GHC
A Scalable I/O Manager for GHCA Scalable I/O Manager for GHC
A Scalable I/O Manager for GHC
 
Agile Management 2013 - Nie tylko it
Agile Management 2013 - Nie tylko itAgile Management 2013 - Nie tylko it
Agile Management 2013 - Nie tylko it
 
Présentation Kivy (et projets associés) à Pycon-fr 2013
Présentation Kivy (et projets associés) à Pycon-fr 2013Présentation Kivy (et projets associés) à Pycon-fr 2013
Présentation Kivy (et projets associés) à Pycon-fr 2013
 
O'Reilly ETech Conference: Laszlo RIA
O'Reilly ETech Conference: Laszlo RIAO'Reilly ETech Conference: Laszlo RIA
O'Reilly ETech Conference: Laszlo RIA
 
Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009
Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009
Wakanda: a new end-to-end JavaScript platform - JSConf Berlin 2009
 
Metasepi team meeting #6: "Snatch-driven development"
Metasepi team meeting #6: "Snatch-driven development"Metasepi team meeting #6: "Snatch-driven development"
Metasepi team meeting #6: "Snatch-driven development"
 
Laszlo PyCon 2005
Laszlo PyCon 2005Laszlo PyCon 2005
Laszlo PyCon 2005
 

Similar to Journey's End – Collection and Reduction in the Stream API

Graal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerGraal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerKoichi Sakata
 
Kotlin fundamentals - By: Ipan Ardian
Kotlin fundamentals - By: Ipan ArdianKotlin fundamentals - By: Ipan Ardian
Kotlin fundamentals - By: Ipan ArdianRizal Khilman
 
Kotlin Fundamentals
Kotlin Fundamentals Kotlin Fundamentals
Kotlin Fundamentals Ipan Ardian
 
Java to Scala: Why & How
Java to Scala: Why & HowJava to Scala: Why & How
Java to Scala: Why & HowGraham Tackley
 
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScriptExtensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScriptBrendan Eich
 
Get started with Lua programming
Get started with Lua programmingGet started with Lua programming
Get started with Lua programmingEtiene Dalcol
 
Lambda/Streams Hands-On Lab
Lambda/Streams Hands-On LabLambda/Streams Hands-On Lab
Lambda/Streams Hands-On LabMaurice Naftalin
 
Kotlin Introduction with Android applications
Kotlin Introduction with Android applicationsKotlin Introduction with Android applications
Kotlin Introduction with Android applicationsThao Huynh Quang
 
Swift Ready for Production?
Swift Ready for Production?Swift Ready for Production?
Swift Ready for Production?Crispy Mountain
 
MLSEV Virtual. From my First BigML Project to Production
MLSEV Virtual. From my First BigML Project to ProductionMLSEV Virtual. From my First BigML Project to Production
MLSEV Virtual. From my First BigML Project to ProductionBigML, Inc
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
Software Uni Conf October 2014
Software Uni Conf October 2014Software Uni Conf October 2014
Software Uni Conf October 2014Nayden Gochev
 
Building Mobile Apps with Android
Building Mobile Apps with AndroidBuilding Mobile Apps with Android
Building Mobile Apps with AndroidKurt Renzo Acosta
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?intelliyole
 

Similar to Journey's End – Collection and Reduction in the Stream API (20)

Journey's end
Journey's endJourney's end
Journey's end
 
Graal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerGraal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT Compiler
 
Kotlin fundamentals - By: Ipan Ardian
Kotlin fundamentals - By: Ipan ArdianKotlin fundamentals - By: Ipan Ardian
Kotlin fundamentals - By: Ipan Ardian
 
Kotlin Fundamentals
Kotlin Fundamentals Kotlin Fundamentals
Kotlin Fundamentals
 
Java to Scala: Why & How
Java to Scala: Why & HowJava to Scala: Why & How
Java to Scala: Why & How
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
 
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScriptExtensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
 
Get started with Lua programming
Get started with Lua programmingGet started with Lua programming
Get started with Lua programming
 
Lambda/Streams Hands-On Lab
Lambda/Streams Hands-On LabLambda/Streams Hands-On Lab
Lambda/Streams Hands-On Lab
 
Scala Introduction
Scala IntroductionScala Introduction
Scala Introduction
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Kotlin Introduction with Android applications
Kotlin Introduction with Android applicationsKotlin Introduction with Android applications
Kotlin Introduction with Android applications
 
Swift Ready for Production?
Swift Ready for Production?Swift Ready for Production?
Swift Ready for Production?
 
MLSEV Virtual. From my First BigML Project to Production
MLSEV Virtual. From my First BigML Project to ProductionMLSEV Virtual. From my First BigML Project to Production
MLSEV Virtual. From my First BigML Project to Production
 
Swift for-rubyists
Swift for-rubyistsSwift for-rubyists
Swift for-rubyists
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Software Uni Conf October 2014
Software Uni Conf October 2014Software Uni Conf October 2014
Software Uni Conf October 2014
 
Building Mobile Apps with Android
Building Mobile Apps with AndroidBuilding Mobile Apps with Android
Building Mobile Apps with Android
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?
 
Kpi driven-java-development
Kpi driven-java-developmentKpi driven-java-development
Kpi driven-java-development
 

Recently uploaded

Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfIdiosysTechnologies1
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 

Recently uploaded (20)

Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdf
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 

Journey's End – Collection and Reduction in the Stream API

  • 1. Journey’s End Collection and Reduction in the Stream API JavaOne, October 2015
  • 2. Developer, designer, architect, teacher, learner, writer Maurice Naftalin Co-author Current Projects www.lambdafaq.org 2
  • 3. • Why collectors? • Using the predefined collectors • Intermission! • Worked problems • Writing your own Journey’s End – Agenda
  • 4. Journey’s End, JavaOne, October 2015 Example Domain city: City name: String age: int Person Person amy = new Person(Athens, "Amy", 21);
 ... List<Person> people = Arrays.asList(jon, amy, bill);

  • 5. Journey’s End, JavaOne, October 2015 Collectors: Journey’s End for a Stream The Life of a Stream Element • Born (at a spliterator) • Transformed (by intermediate operations) • Collected (by a terminal operation)
  • 6. Journey’s End, JavaOne, October 2015 Collectors: Journey’s End for a Stream The Life of a Stream Element • Born (at a spliterator) • Transformed (by intermediate operations) • Collected (by a terminal operation)
  • 7. Journey’s End, JavaOne, October 2015 Collectors: Journey’s End for a Stream The Life of a Stream Element • Born (at a spliterator) • Transformed (by intermediate operations) • Collected (by a terminal operation)
  • 8. Journey’s End, JavaOne, October 2015 Collectors: Journey’s End for a Stream The Life of a Stream Element • Born (at a spliterator) • Transformed (by intermediate operations) • Collected (by a terminal operation)
  • 9. Journey’s End, JavaOne, October 2015 Collectors: Journey’s End for a Stream ? The Life of a Stream Element • Born (at a spliterator) • Transformed (by intermediate operations) • Collected (by a terminal operation)
  • 10. Journey’s End, JavaOne, October 2015 Terminal Operations – Search operations – Side-effecting operations – Reductions

  • 11. Journey’s End, JavaOne, October 2015 Search Operations Search operations - • allMatch, anyMatch • findAny, findFirst boolean allAdults = people.stream()
 .allMatch(p -> p.getAge() >= 21);

  • 12. Journey’s End, JavaOne, October 2015 Side-effecting Operations Side-effecting operations • forEach, forEachOrdered
 
 people.stream()
 .forEach(System.out::println); • So could we calculate total ages like this?
 
 int sum = 0;
 people.stream()
 .mapToInt(Person::getAge)
 .forEach(a -> { sum += a }); people.stream()
 .forEach(System.out::println);
 int sum = 0;
 people.stream()
 .mapToInt(Person::getAge)
 .forEach(a -> { sum += a; });

  • 13. Journey’s End, JavaOne, October 2015 Side-effecting Operations Side-effecting operations • forEach, forEachOrdered
 
 people.stream()
 .forEach(System.out::println); • So could we calculate total ages like this?
 
 int sum = 0;
 people.stream()
 .mapToInt(Person::getAge)
 .forEach(a -> { sum += a }); people.stream()
 .forEach(System.out::println);
 int sum = 0;
 people.stream()
 .mapToInt(Person::getAge)
 .forEach(a -> { sum += a; });
 Don’t do this!
  • 14. Journey’s End, JavaOne, October 2015 • Using an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); int sum = 0; for (int i = 0 ; i < vals.length ; i++) { sum += vals[i]; }

  • 15. Journey’s End, JavaOne, October 2015 • Using an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); int sum = 0; for (int i = 0 ; i < vals.length ; i++) { sum += vals[i]; }
 0 1 2 3 + +
  • 16. Journey’s End, JavaOne, October 2015 • Using an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); int sum = 0; for (int i = 0 ; i < vals.length ; i++) { sum += vals[i]; }
 0 1 2 3 + + +
  • 17. Journey’s End, JavaOne, October 2015 • Avoiding an accumulator: Reduction – Why?
  • 18. Journey’s End, JavaOne, October 2015 • Avoiding an accumulator: Reduction – Why?
  • 19. Journey’s End, JavaOne, October 2015 • Avoiding an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); OptionalInt sum = Arrays.stream(vals) .reduce((a,b) -> a + b);
 + + + 1 2 30
  • 20. Journey’s End, JavaOne, October 2015 • Avoiding an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); OptionalInt sum = Arrays.stream(vals) .reduce((a,b) -> a + b);
 + + + 1 2 30 + + +
  • 21. Journey’s End, JavaOne, October 2015 • Avoiding an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); OptionalInt sum = Arrays.stream(vals) .reduce((a,b) -> a + b);
 BinaryOperator must be associative! + + + 1 2 30 + + +
  • 22. Journey’s End, JavaOne, October 2015 • Avoiding an accumulator: Reduction – Why? int[] vals = new int[100]; Arrays.setAll(vals, i -> i); OptionalInt sum = Arrays.stream(vals) .reduce((a,b) -> a + b);
 BinaryOperator must be associative! a + (b + c) = (a + b) + c + + + 1 2 30 + + +
  • 23. Journey’s End, JavaOne, October 2015 Why Reduction? 0 1 2 3 4 5 6 7 + + + + + + +
  • 24. Journey’s End, JavaOne, October 2015 Why Reduction? 0 1 2 3 4 5 6 7 + + + + + + +
  • 25. Journey’s End, JavaOne, October 2015 Why Reduction? 0 1 2 3 4 5 6 7 + + + + + + + Intermediate operations
  • 26. Journey’s End, JavaOne, October 2015 Reduction on ImmutableValues Reduction works on immutable values too BigDecimal[] vals = new BigDecimal[100]; Arrays.setAll(vals, i -> new BigDecimal(i)); Optional<BigDecimal> sum = Arrays.stream(vals) .reduce(BigDecimal::add);

  • 27. Journey’s End, JavaOne, October 2015 Reduction on ImmutableValues Reduction works on immutable values too BigDecimal[] vals = new BigDecimal[100]; Arrays.setAll(vals, i -> new BigDecimal(i)); Optional<BigDecimal> sum = Arrays.stream(vals) .reduce(BigDecimal::add);

  • 28. Journey’s End, JavaOne, October 2015 Reduction to Collections?
  • 29. Journey’s End, JavaOne, October 2015 Reduction to Collections? This also works with collections – sort of ... • for each element, client code creates a new empty collection and adds the single element to it • combines collections using addAll
  • 30. Journey’s End, JavaOne, October 2015 Reduction to Collections? This also works with collections – sort of ... • for each element, client code creates a new empty collection and adds the single element to it • combines collections using addAll We can do better!
  • 31. Journey’s End, JavaOne, October 2015 Reduction over an Identity BigDecimal[] vals = new BigDecimal[100]; Arrays.setAll(vals, i -> new BigDecimal(i)); BigDecimal sum = Arrays.stream(vals) .reduce(BigDecimal.ZERO,BigDecimal::add);

  • 32. Journey’s End, JavaOne, October 2015 Reduction over an Identity BigDecimal[] vals = new BigDecimal[100]; Arrays.setAll(vals, i -> new BigDecimal(i)); BigDecimal sum = Arrays.stream(vals) .reduce(BigDecimal.ZERO,BigDecimal::add);
 Works for immutable objects:
  • 33. Journey’s End, JavaOne, October 2015 Reduction over an Identity + + + 0 1 2 3 + + + 0 4 5 6 7 0 ++ +
  • 34. Journey’s End, JavaOne, October 2015 Reduction to Collections?
  • 35. Journey’s End, JavaOne, October 2015 Reduction to Collections? Reduction over an identity doesn’t work with collections at all • reduction reuses the identity element
  • 36. Journey’s End, JavaOne, October 2015 Reduction to Collections? Reduction over an identity doesn’t work with collections at all • reduction reuses the identity element We’ve got to do better!
  • 37. Journey’s End, JavaOne, October 2015 The Answer – Collectors a a a e0 e1 e2 e3 a a a e4 e5 e6 e7 aa c a: accumulator c: combiner
  • 38. Journey’s End, JavaOne, October 2015 The Answer – Collectors a a a e0 e1 e2 e3 a a a () -> [] e4 e5 e6 e7 aa c a: accumulator c: combiner () -> []
  • 39. Journey’s End, JavaOne, October 2015 Collectors So to define a collector, you need to provide • Supplier • Accumulator • Combiner That sounds really hard! Good then that we don’t have to do it • – very often
  • 40. Journey’s End, JavaOne, October 2015 Collectors API Factory methods in the Collectors class.They produce standalone collectors, accumulating to: • framework-supplied containers; • custom collections; • classification maps.
  • 41. • Why collectors? • Using the predefined collectors • Intermission! • Worked problems • Writing your own Journey’s End – Agenda
  • 42. Journey’s End, JavaOne, October 2015 Predefined Standalone Collectors – from factory methods in Collections class • toList(), toSet(), toMap(), joining() • toMap(), toCollection() groupingBy(), partitioningBy(), groupingByConcurrent() Using the Predefined Collectors
  • 43. Journey’s End, JavaOne, October 2015 Predefined Standalone Collectors – from factory methods in Collections class • toList(), toSet(), toMap(), joining() • toMap(), toCollection() groupingBy(), partitioningBy(), groupingByConcurrent() Using the Predefined Collectors framework provides the Supplier
  • 44. Journey’s End, JavaOne, October 2015 Predefined Standalone Collectors – from factory methods in Collections class • toList(), toSet(), toMap(), joining() • toMap(), toCollection() groupingBy(), partitioningBy(), groupingByConcurrent() Using the Predefined Collectors user provides the Supplier framework provides the Supplier
  • 45. Journey’s End, JavaOne, October 2015 Predefined Standalone Collectors – from factory methods in Collections class • toList(), toSet(), toMap(), joining() • toMap(), toCollection() groupingBy(), partitioningBy(), groupingByConcurrent() Using the Predefined Collectors user provides the Supplier framework provides the Supplier produce a 
 classification map
  • 46. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Collectors.toSet() people.stream().collect(Collectors.toSet())
  • 47. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) Collector<Person,?,Set<Person>>
  • 48. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) bill Collector<Person,?,Set<Person>>
  • 49. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) bill Collector<Person,?,Set<Person>>
  • 50. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) bill Collector<Person,?,Set<Person>>
  • 51. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) bill jon Collector<Person,?,Set<Person>>
  • 52. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) bill jon Collector<Person,?,Set<Person>>
  • 53. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) amy bill jon Collector<Person,?,Set<Person>>
  • 54. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Stream<Person> Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) amy bill jon Collector<Person,?,Set<Person>>
  • 55. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Collectors.toSet() Set<Person> people.stream().collect(Collectors.toSet()) amy bill jon Collector<Person,?,Set<Person>>
  • 56. Journey’s End, JavaOne, October 2015 Simple Collector – toSet() Collectors.toSet() Set<Person> { , , } people.stream().collect(Collectors.toSet()) amybilljon Collector<Person,?,Set<Person>>
  • 57. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) people.stream().collect( Collectors.toMap( Person::getCity,
 Person::getName))
  • 58. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> Collector<Person,?,Map<City,String> people.stream().collect(toMap(Person::getCity,Person::getName))
  • 59. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> Collector<Person,?,Map<City,String>
  • 60. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> bill
  • 61. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> bill Person::getCity
  • 62. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> London bill
  • 63. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> London bill Person::getName
  • 64. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> London “Bill” bill Person::getName
  • 65. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> London “Bill”
  • 66. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> amy London “Bill”
  • 67. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> Athens amy London “Bill”
  • 68. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> “Amy”Athens London “Bill”
  • 69. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> “Amy”Athens jon London “Bill”
  • 70. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> “Amy”Athens London “Bill” Tulsa “Jon”
  • 71. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) toMap() Map<City,String> “Amy”Athens London “Bill” Tulsa “Jon”
  • 72. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) toMap() Map<City,String> “Amy”Athens London “Bill” Tulsa “Jon”
  • 73. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String>
  • 74. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> “Amy”Athens jon London “Bill”
  • 75. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> “Amy”Athens jon London “Bill” Athens
  • 76. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper) Stream<Person> toMap() Map<City,String> “Amy”Athens jon London IllegalStateException “Bill” Athens
  • 77. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) people.stream().collect( Collectors.toMap( Person::getCity,
 Person::getName, (a,b) -> a.concat(b)))
  • 78. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) Stream<Person> toMap() Map<City,String>
  • 79. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) Stream<Person> toMap() Map<City,String> “Amy”Athens London “Bill” Athens
  • 80. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) Stream<Person> toMap() Map<City,String> “Amy”Athens London “Bill” Athens
  • 81. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) Stream<Person> toMap() Map<City,String> “Amy”Athens London “Bill” “Jon” Athens
  • 82. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) Stream<Person> toMap() Map<City,String> “Amy”Athens London “Bill” “Jon” (a,b) -> a.concat(b) Athens
  • 83. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) Stream<Person> toMap() Map<City,String> Athens London “Bill” (a,b) -> a.concat(b) “AmyJon” Athens
  • 84. Journey’s End, JavaOne, October 2015 Collectors API Factory methods in the Collectors class.They produce standalone collectors, accumulating to: • framework-supplied containers; • custom collections; • classification maps.
  • 85. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction) toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction, Supplier<M> mapFactory) people.stream().collect( Collectors.toMap( Person::getCity,
 Person::getName, (a,b) -> a.concat(b),
 TreeMap::new))
  • 86. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction, Supplier<M> mapFactory) Stream<Person> toMap() Map<City,String>
  • 87. Journey’s End, JavaOne, October 2015 toMap(Function<T,K> keyMapper, Function<T,U> valueMapper BinaryOperator<U> mergeFunction, Supplier<M> mapFactory) Stream<Person> toMap() Map<City,String>
  • 88. Journey’s End, JavaOne, October 2015 Collecting to Custom Collections <C extends Collection<T>> NavigableSet<String> sortedNames = people.stream() .map(Person::getName)
 .collect(toCollection(TreeSet::new));
  • 89. Journey’s End, JavaOne, October 2015 Collecting to Custom Collections toCollection(Supplier<C> collectionFactory) <C extends Collection<T>> NavigableSet<String> sortedNames = people.stream() .map(Person::getName)
 .collect(toCollection(TreeSet::new));
  • 90. Journey’s End, JavaOne, October 2015 Collectors API Factory methods in the Collectors class.They produce standalone collectors, accumulating to: • framework-supplied containers; • custom collections; • classification maps.
  • 91. Journey’s End, JavaOne, October 2015 Collecting to Classification Maps groupingBy • simple • with downstream • with downstream and map factory partitioningBy
  • 92. Journey’s End, JavaOne, October 2015 groupingBy(Function<T,K> classifier) Uses the classifier function to make a classification mapping Like toMap(), except that the values placed in the map are lists of the elements, one List corresponding to each classification key: For example, use Person.getCity() to make a Map<City,List<Person>> Map<City,List<Person>> peopleByCity = people.stream().
 collect(Collectors.groupingBy(Person::getCity));
  • 93. Journey’s End, JavaOne, October 2015 Stream<Person> groupingBy() Map<City,List<Person>> bill jon amy Athens London Collector<Person,?,Map<City,List<Person> groupingBy(Function<Person,City>) Classifier Person→City
  • 94. Journey’s End, JavaOne, October 2015 Stream<Person> groupingBy() Map<City,List<Person>> bill jon amy Athens London groupingBy(Function<Person,City>)
  • 95. Journey’s End, JavaOne, October 2015 Stream<Person> groupingBy() Map<City,List<Person>> bill jon amy Athens bill London groupingBy(Function<Person,City>)
  • 96. Journey’s End, JavaOne, October 2015 Stream<Person> groupingBy() Map<City,List<Person>> bill jon amy Athens billLondon groupingBy(Function<Person,City>) [ ]
  • 97. Journey’s End, JavaOne, October 2015 Stream<Person> groupingBy() Map<City,List<Person>> bill jon amy Athens [ ] bill amy London groupingBy(Function<Person,City>) [ ]
  • 98. Journey’s End, JavaOne, October 2015 Stream<Person> groupingBy() Map<City,List<Person>> bill jon amy Athens [ ] [ , ]bill amy jonLondon groupingBy(Function<Person,City>)
  • 99. Journey’s End, JavaOne, October 2015 groupingBy() Map<City,List<Person>> bill jon amy Athens [ ] [ , ]bill amy jonLondon groupingBy(Function<Person,City>)
  • 100. Journey’s End, JavaOne, October 2015 groupingBy() Map<City,List<Person>> bill jon amy Athens [ ] [ , ]bill amy jonLondon groupingBy(Function<Person,City>)
  • 101. Journey’s End, JavaOne, October 2015 groupingBy(Function<T,K> classifier) Uses the classifier function to make a classification mapping Like toMap(), except that the values placed in the map are lists of the elements, one List corresponding to each classification key: For example, use Person.getCity() to make a Map<City,List<Person>> Map<City,List<Person>> peopleByCity = people.stream().
 collect(Collectors.groupingBy(Person::getCity));
  • 102. Journey’s End, JavaOne, October 2015 groupingBy(classifier, downstream) Map<City,List<Person>> peopleByCity = people.stream().
 collect(Collectors.groupingBy(Person::getCity,toSet())); Uses the classifier function to make a classification mapping into a container defined by a downstream Collector Like toMap(), except that the values placed in the map are containers of the elements, one container corresponding to each classification key: For example, use Person.getCity() to make a Map<City,Set<Person>> Map<City,Set<Person>> peopleByCity = people.stream().
 collect(Collectors.groupingBy(Person::getCity,toSet()));
  • 103. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens Downstream Collector — toSet() Stream<Person > Classifier Person→City
  • 104. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens
  • 105. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens bill
  • 106. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens bill
  • 107. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens bill
  • 108. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athensamy bill
  • 109. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens amy bill
  • 110. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens amy bill
  • 111. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens amy jon bill
  • 112. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) Stream<Person> groupingBy() Map<City,Set<Person> bill jon amy London Athens amy jon bill
  • 113. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) groupingBy() Map<City,Set<Person> bill jon amy London Athens amy jon bill
  • 114. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) groupingBy() Map<City,Set<Person> bill jon amy London Athens amy jon bill
  • 115. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) groupingBy() Map<City,Set<Person> bill jon amy London Athens { }amy { , }jonbill
  • 116. Journey’s End, JavaOne, October 2015 groupingBy(Function classifier,Collector downstream)) groupingBy() Map<City,Set<Person> bill jon amy London Athens { }amy { , }jonbill
  • 117. Journey’s End, JavaOne, October 2015 mapping(Function mapper,Collector downstream)) Applies a mapping function to each input element before passing it to the downstream collector. Set<City> inhabited = people.stream()
 .collect(mapping(Person::getCity,toSet())); Map<City,String> namesByCity = people.stream()
 .collect(groupingBy(Person::getCity, mapping(Person::getName,joining())); Animation example Sensible example
  • 126. Dualling Convenience Reductions • Collectors.counting() • Collectors.maxBy • Collectors.minBy • Collectors.summarizingXXX 42
  • 127. Journey’s End, JavaOne, October 2015 Concurrent Collection
  • 128. Journey’s End, JavaOne, October 2015 Thread safety is guaranteed by the framework • Even for non-threadsafe containers! Concurrent Collection
  • 129. Journey’s End, JavaOne, October 2015 Thread safety is guaranteed by the framework • Even for non-threadsafe containers! But at a price... So what if your container is already threadsafe? • A concurrentMap implementation, for example? Concurrent Collection
  • 130. Journey’s End, JavaOne, October 2015 Thread safety is guaranteed by the framework • Even for non-threadsafe containers! But at a price... So what if your container is already threadsafe? • A concurrentMap implementation, for example? Concurrent Collection
  • 131. Journey’s End, JavaOne, October 2015 Thread safety is guaranteed by the framework • Even for non-threadsafe containers! But at a price... So what if your container is already threadsafe? • A concurrentMap implementation, for example? Every overload of toMap() and groupingBy() has a dual • toConcurrentMap(...) • groupingByConcurrent(...) Concurrent Collection
  • 132. • Why collectors? • Using the predefined collectors • Intermission! • Worked problems • Writing your own Journey’s End – Agenda
  • 133. • Why collectors? • Using the predefined collectors • Intermission! • Worked problems • Writing your own Journey’s End – Agenda
  • 134. Journey’s End, JavaOne, October 2015 Writing a Collector Why would you want to?
  • 135. Journey’s End, JavaOne, October 2015 Writing a Collector Why would you want to? • accumulate to a container that doesn’t implement Collection
  • 136. Journey’s End, JavaOne, October 2015 Writing a Collector Why would you want to? • accumulate to a container that doesn’t implement Collection • share state between values being collected
  • 137. Journey’s End, JavaOne, October 2015 Oprah’s Problem
  • 138. Journey’s End, JavaOne, October 2015 Oprah’s Problem How to find a book?
  • 139. Journey’s End, JavaOne, October 2015 Oprah’s Problem How to find a book? 336 640 144 624 Page count 239 640 384 1104 172 400
  • 140. Journey’s End, JavaOne, October 2015 What Oprah Needs New Earth 0 Poisonwood Bible 336 Night 976 A Fine Balance 1120 ... Cumulative page counts
  • 141. Supplier and Accumulator “NE” 336 0 “PB” 640 336[ ], ]“NE” 336 0[ ][ aNewEarth thePoisonwoodBible accumulator accumulator
  • 142. Combiner ,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
  • 143. Combiner ,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ], ,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
  • 144. Combiner combiner ,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ], ,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
  • 145. Combiner combiner ,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ], ,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , , 976
  • 146. Combiner combiner ,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ], ,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , , 976
  • 147. Combiner combiner ,“Night” 144 0[ “AFB” 624 144 ]“NE” 336 0 “PB” 640 336[ ], ,“Night” 144 976 “AFB” 624 1120 ]“NE” 336 0 “PB” 640 336[ , ,
  • 148. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] newEarth poisonwood night
  • 149. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] newEarth poisonwood night Page count Start displacement
  • 150. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] ]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[ newEarth poisonwood night
  • 151. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] ]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[ newEarth poisonwood night Map
  • 152. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] ]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[ newEarth poisonwood night Reduce Map
  • 153. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] ]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[ PartialResult::new ArrayDeque::new newEarth poisonwood night Reduce Map
  • 154. Using Reduction Instead... “New Earth” 336 0 “Poisonwood Bible” 640 336[ , “Night” 144 976, ] ]“New Earth” 336 0 “Poisonwood Bible” 640 0[ ] ]“Night” 144 0 ][[ PartialResult::new ArrayDeque::new PartialResult::new ArrayDeque::new PartialResult::new ArrayDeque::new newEarth poisonwood night Reduce
  • 155. Journey’s End, JavaOne, October 2015 Performance of Collectors Depends on the performance of accumulator and combiner functions • toList(), toSet(), toCollection – performance will probably be dominated by accumulator, but remember that the framework will need to manage multithread access to non-threadsafe containers for the combine operation toMap(), toConcurrentMap() • map merging is slow. Resizing maps, especially concurrent maps, is particularly expensive.Whenever possible, presize all data structures, maps in particular.
  • 156. Journey’s End, JavaOne, October 2015 Conclusion Collectors • generalisation of reduction • allow a functional style while continuing to work with a language based on mutation • designed for composition • flexible and powerful programming tool • take a bit of getting used to! – but they’re worth it!
  • 157. Journey’s End, JavaOne, October 2015 Questions?