overview of java 8 streams (part 5) - vanderbilt …schmidt/cs891f/2018-pdfs/09-java...2 learning...

38
Overview of Java 8 Streams (Part 5) Douglas C. Schmidt [email protected] www.dre.vanderbilt.edu/~schmidt Professor of Computer Science Institute for Software Integrated Systems Vanderbilt University Nashville, Tennessee, USA

Upload: others

Post on 06-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

Overview of Java 8 Streams (Part 5)

Douglas C. [email protected]

www.dre.vanderbilt.edu/~schmidt

Professor of Computer Science

Institute for Software

Integrated Systems

Vanderbilt University

Nashville, Tennessee, USA

Page 2: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

2

Learning Objectives in this Part of the Lesson• Understand the structure & functionality of Java 8 streams, e.g.,

• Fundamentals of streams

• Common stream aggregate operations

• “Splittable iterators” (Spliterators)

• Terminating a stream

• Implementing non-concurrent collectors for sequential streams

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

Page 3: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

3

Implementing a Non-Concurrent Collector

Page 4: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

4

• A collector is used to terminate a stream

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

Implementing a Non-Concurrent Collectorvoid runCollectToList() {

List<String> characters = Arrays

.asList("horatio", "laertes",

"Hamlet, ...);

List<String> results =

characters

.stream()

.filter(s ->

toLowerCase(…) =='h')

.map(this::capitalize)

.sorted()

.collect(toList()); ...

Collect the results into a ArrayList

Page 5: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

5

• A collector is used to terminate a stream

• Collector defines an interface whose implementations can accumulate input elements in a mutable result container

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

Implementing a Non-Concurrent Collector

Page 6: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

6

• Collector implementations can either benon-concurrent or concurrent based on their characteristics

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.Characteristics.html

Implementing a Non-Concurrent Collector

Page 7: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

7

• Collector implementations can either benon-concurrent or concurrent based on their characteristics

• This distinction is only relevant forparallel streams

Implementing a Non-Concurrent Collector

filter(not(this::urlCached))

collect(toList())

map(this::downloadImage)

flatMap(this::applyFilters)

Page 8: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

8

• Collector implementations can either benon-concurrent or concurrent based on their characteristics

• This distinction is only relevant forparallel streams

• Our focus here is on non-concurrentcollectors for sequential streams

Non-concurrent & concurrent collectors for parallel streams are covered later

Implementing a Non-Concurrent Collector

filter(not(this::urlCached))

collect(toList())

map(this::downloadImage)

flatMap(this::applyFilters)

Page 9: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

9

• A non-concurrent collector for a sequential stream simply accumulates elements into a mutable result container

Implementing a Non-Concurrent Collector

Page 10: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

10

• A collector is essentially the inverse of a spliterator

Implementing a Non-Concurrent Collector

join joinjoin

Processsequentially

Processsequentially

Processsequentially

Processsequentially

InputString1.1 InputString1.2 InputString2.1 InputString2.2

InputString1 InputString2

trySplit()

InputString

trySplit() trySplit()

Page 11: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

11

• A collector is essentially the inverse of a spliterator

Implementing a Non-Concurrent Collector

join joinjoin

Processsequentially

Processsequentially

Processsequentially

Processsequentially

InputString1.1 InputString1.2 InputString2.1 InputString2.2

InputString1 InputString2

trySplit()

InputString

trySplit() trySplit()

A spliterator splits a single input source into a stream of elements

Page 12: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

12

• A collector is essentially the inverse of a spliterator

Implementing a Non-Concurrent Collector

join joinjoin

Processsequentially

Processsequentially

Processsequentially

Processsequentially

InputString1.1 InputString1.2 InputString2.1 InputString2.2

InputString1 InputString2

trySplit()

InputString

trySplit() trySplit()

A collector combines a stream of elements back into a single result

Page 13: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

13See www.baeldung.com/java-8-collectors

Implementing a Non-Concurrent Collector• The Collector interface defines

three generic types

Page 14: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

14

Implementing a Non-Concurrent Collector• The Collector interface defines

three generic types

• T – The type of objects available

in the stream

• e.g., Integer, String, etc.

Page 15: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

15

Implementing a Non-Concurrent Collector• The Collector interface defines

three generic types

• T

• A – The type of a mutable accumulator object for collection

• e.g., List of T (implementedvia ArrayList or LinkedList)

Page 16: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

16

Implementing a Non-Concurrent Collector• The Collector interface defines

three generic types

• T

• A

• R – The type of a final result

• e.g., List of T

Page 17: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

17

• Five methods are defined in the Collector interface

Implementing a Non-Concurrent Collector

Again, this discussion assumes we’re implementing a non-concurrent collector

Page 18: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

18

• Five methods are defined in the Collector interface

• characteristics() – provides a

stream with additional information used for internal optimizations, e.g.

• UNORDERED

• The collector need not preservethe encounter order

Implementing a Non-Concurrent Collector

Page 19: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

19

• Five methods are defined in the Collector interface

• characteristics() – provides a

stream with additional information used for internal optimizations, e.g.

• UNORDERED

• The collector need not preservethe encounter order

Implementing a Non-Concurrent Collector

A collector may preserve encounter order if it incurs no additional overhead

Page 20: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

20

• Five methods are defined in the Collector interface

• characteristics() – provides a

stream with additional information used for internal optimizations, e.g.

• UNORDERED

• IDENTITY_FINISH

• The finisher() is the identity function so it can be a no-op

• e.g., finisher() just returns null

Implementing a Non-Concurrent Collector

Page 21: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

21

• Five methods are defined in the Collector interface

• characteristics() – provides a

stream with additional information used for internal optimizations, e.g.

• UNORDERED

• IDENTITY_FINISH

• CONCURRENT

• The accumulator() method is called concurrently on the result container

Implementing a Non-Concurrent Collector

The mutable result container must be synchronized!!

Page 22: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

22

• Five methods are defined in the Collector interface

• characteristics() – provides a

stream with additional information used for internal optimizations, e.g.

• UNORDERED

• IDENTITY_FINISH

• CONCURRENT

• The accumulator() method is called concurrently on the result container

Implementing a Non-Concurrent Collector

We’re focusing on a non-concurrent collector, which doesn’t enable CONCURRENT

Page 23: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

23

• Five methods are defined in the Collector interface

• characteristics() – provides a

stream with additional information used for internal optimizations, e.g.

Implementing a Non-Concurrent Collector

See docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

Set characteristics() {

return Collections.unmodifiableSet

(EnumSet.of(Collector.Characteristics.CONCURRENT,

Collector.Characteristics.UNORDERED,

Collector.Characteristics.IDENTITY_FINISH));

}

Any/all characteristics can be set using EnumSet.of()

Page 24: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

24

• Five methods are defined in the Collector interface

• characteristics()

• supplier() – returns a supplier

instance that acts as a factory togenerate an empty result container, e.g.

Implementing a Non-Concurrent Collector

Supplier<List> supplier() {

return ArrayList::new;

}

Page 25: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

25

• Five methods are defined in the Collector interface

• characteristics()

• supplier()

• accumulator() – returns a bi-

consumer that adds a new element to an existing result container, e.g.

Implementing a Non-Concurrent Collector

BiConsumer<List, Integer> accumulator() {

return List::add;

}

A non-concurrent collector needs no synchronization

Page 26: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

26

• Five methods are defined in the Collector interface

• characteristics()

• supplier()

• accumulator()

• combiner() – returns a binary

operator that merges two result containers together, e.g.

Implementing a Non-Concurrent Collector

This combiner() will not be called for a sequential stream..

BinaryOperator<List> combiner() {

return (one, another) -> {

one.addAll(another);

return one;

}};

Page 27: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

27

• Five methods are defined in the Collector interface

• characteristics()

• supplier()

• accumulator()

• combiner()

• finisher() – returns a function

that converts the result containerto final result type, e.g.

• return Function.identity()

Implementing a Non-Concurrent Collector

Page 28: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

28

• Five methods are defined in the Collector interface

• characteristics()

• supplier()

• accumulator()

• combiner()

• finisher() – returns a function

that converts the result containerto final result type, e.g.

• return Function.identity()

• return null;

Implementing a Non-Concurrent Collector

Should be a no-op if IDENTITY_FINISH characteristic is set

Page 29: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

29

• Five methods are defined in the Collector interface

• characteristics()

• supplier()

• accumulator()

• combiner()

• finisher() – returns a function

that converts the result containerto final result type, e.g.

• return Function.identity()

• return null;

Implementing a Non-Concurrent Collector

See Java8/ex19/src/main/java/utils/FuturesCollector.java

Stream

.generate(() ->

makeBigFraction

(new Random(), false))

.limit(sMAX_FRACTIONS)

.map(reduceAndMultiplyFraction)

.collect(FuturesCollector

.toFuture())

.thenAccept

(this::sortAndPrintList);

finisher() can also be much more interesting!

Page 30: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

30

Implementing a Non-Concurrent Collector

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

• Collectors is a utility class whosefactory methods create collectors for common collection types

Page 31: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

31

Implementing a Non-Concurrent Collector

See www.quora.com/What-is-the-best-way-to-write-utility-classes-in-Java/answer/Jon-Harley

• Collectors is a utility class whosefactory methods create collectors for common collection types

• A utility class is a final classhaving only static methods, no state, & a private constructor

Page 32: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

32

Implementing a Non-Concurrent Collector

See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toList

• Collectors is a utility class whosefactory methods create collectors for common collection types

• e.g., returns a Collector that accumulates input elements into a new (Array)List

final class Collectors {

...

public static <T> Collector

<T, ?, List<T>>

toList() {

return new CollectorImpl<>

((Supplier<List<T>>)

ArrayList::new,

List::add,

(left, right) -> {

left.addAll(right);

return left;

},

CH_ID);

} ...

Page 33: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

33

Implementing a Non-Concurrent Collector

See openjdk/8-b132/java/util/stream/Collectors.java#Collectors.CollectorImpl

• CollectorImpl defines a simple (private)implementation class for a Collector

Page 34: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

34

Implementing a Non-Concurrent Collector

See openjdk/8-b132/java/util/stream/Collectors.java#Collectors.CollectorImpl

• Collector.of() defines a simple (public) factory method thatimplements a Collector using(private) CollectorImpl

interface Collector<T, A, R> {

...

static<T, R> Collector<T, R, R> of

(Supplier<R> supplier,

BiConsumer<R, T> accumulator,

BinaryOperator<R> combiner,

Characteristics... chars) {

...

return new Collectors

.CollectorImpl<>

(supplier,

accumulator,

combiner,

chars);

} ...

Page 35: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

35

Implementing a Non-Concurrent Collector

See SimpleSearchStream/src/main/java/search/SearchResults.java

• Collector.of() can also implement custom collectors that have pithy lambdas

public String toString() {

...

mList.stream()

.collect(Collector.of(() -> new StringJoiner("|"),

(j, r) -> j.add(r.toString()),

StringJoiner::merge,

StringJoiner::toString)); ...

SearchResults’s custom collector formats itself

Page 36: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

36

Implementing a Non-Concurrent Collector

See Java8/ex19/src/main/java/utils/FuturesCollector.java

• Complex custom collectors should implement the Collector interface

Page 37: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

37See www.youtube.com/watch?v=H7VbRz9aj7c

• More information on implementing custom collectors is available online

Implementing a Non-Concurrent Collector

Page 38: Overview of Java 8 Streams (Part 5) - Vanderbilt …schmidt/cs891f/2018-PDFs/09-Java...2 Learning Objectives in this Part of the Lesson •Understand the structure & functionality

38

End of Overview of Java 8 Streams (Part 5)