overview of java 8 streams (part 4) - vanderbilt …schmidt/cs891f/2018-pdfs/08-java...4 •every...
TRANSCRIPT
![Page 1: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/1.jpg)
Overview of Java 8 Streams (Part 4)
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 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/2.jpg)
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
![Page 3: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/3.jpg)
3
Terminating a Stream
![Page 4: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/4.jpg)
4
• Every stream finishes with a terminal operation that yields a non-stream result
Intermediate operation (behavior f)
Intermediate operation (behavior g)
Terminal operation (behavior h)
Output f(x)
Output g(f(x))
…
Input x
Terminating a Stream
See github.com/douglascraigschmidt/LiveLessons/tree/master/Java8/ex12
Stream
.of("horatio",
"laertes",
"Hamlet", ...)
.filter(s -> toLowerCase
(s.charAt(0)) == 'h')
.map(this::capitalize)
.sorted()
.forEach(System.out::println);
![Page 5: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/5.jpg)
5
• Every stream finishes with a terminal operation that yields a non-stream result, e.g.
• No value at all
• i.e., only side-effects!
Terminating a Stream
![Page 6: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/6.jpg)
6
• Every stream finishes with a terminal operation that yields a non-stream result, e.g.
• No value at all
• The result of a reduction operation
Terminating a Stream
See docs.oracle.com/javase/tutorial/collections/streams/reduction.html
![Page 7: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/7.jpg)
7
• Several terminal operations returnno value at all
Terminating a Streamvoid runForEach() {
...
Stream
.of("horatio", "laertes",
"Hamlet", ...)
.filter(s -> toLowerCase
(s.charAt(0)) == 'h')
.map(this::capitalize)
.sorted()
.forEach
(System.out::println);
...
See github.com/douglascraigschmidt/LiveLessons/tree/master/Java8/ex12
![Page 8: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/8.jpg)
8
• Several terminal operations returnno value at all
Terminating a Stream
See docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#forEach
void runForEach() {
...
Stream
.of("horatio", "laertes",
"Hamlet", ...)
.filter(s -> toLowerCase
(s.charAt(0)) == 'h')
.map(this::capitalize)
.sorted()
.forEach
(System.out::println);
...
Performs the designated action on each element of this stream
![Page 9: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/9.jpg)
9
• Several terminal operations returnno value at all
Terminating a Streamvoid runForEach() {
List<String> results =
new ArrayList<>();
Stream
.of("horatio", "laertes",
"Hamlet", ...)
.filter(s -> toLowerCase
(s.charAt(0)) == 'h')
.map(this::capitalize)
.sorted()
.forEach
(results::add);
...
The lambda passed to forEach() is allowed to have side-effects
See www.logicbig.com/tutorials/core-java-tutorial/java-util-stream/side-effects
![Page 10: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/10.jpg)
10
• Several terminal operations returnno value at all
Terminating a Streamvoid runForEach() {
List<String> results =
new ArrayList<>();
Stream
.of("horatio", "laertes",
"Hamlet", ...)
.parallel()
.filter(s -> toLowerCase
(s.charAt(0)) == 'h')
.map(this::capitalize)
.sorted()
.forEach
(results::add);
...
Avoid using forEach() with side-effects in a parallel stream!!!
See docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#side_effects
![Page 11: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/11.jpg)
11
• Other terminal operations returnthe result of a reduction operation
Terminating a Stream
See docs.oracle.com/javase/tutorial/collections/streams/reduction.html
void runCollectTo*() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
...<String> results =
characters
.stream()
.filter(s ->
toLowerCase(…) =='h')
.map(this::capitalize)
.sorted()
.collect(...); ...
![Page 12: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/12.jpg)
12See docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectTo*() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
...<String> results =
characters
.stream()
.filter(s ->
toLowerCase(…) =='h')
.map(this::capitalize)
.sorted()
.collect(...); ...
Terminating a Stream
Performs a mutable reduction on all elements of this stream using some type of collector
![Page 13: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/13.jpg)
13See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectTo*() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
...<String> results =
characters
.stream()
.filter(s ->
toLowerCase(…) =='h')
.map(this::capitalize)
.sorted()
.collect(...); ...
Terminating a Stream
A collector performs reduction operations, e.g., summarizing elements according to various criteria, accumulating elements into various types of collections, etc.
![Page 14: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/14.jpg)
14See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toList
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectToList() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet, ...);
List<String> results =
characters
.stream()
.filter(s ->
toLowerCase(…) =='h')
.map(this::capitalize)
.sorted()
.collect(toList()); ...
Terminating a Stream
Collect the results into a ArrayList
![Page 15: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/15.jpg)
15
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectToSet() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
Set<String> results =
characters
.stream()
.filter(s ->
toLowerCase(…) =='h')
.map(this::capitalize)
.collect(toSet()); ...
Terminating a Stream
Collect the results into a HashSet,which has no duplicate entries
See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toSet
![Page 16: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/16.jpg)
16
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectToMap() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
Map<String, Integer> results =
characters
.stream()
.filter(s ->
toLowerCase(…) =='h')
.map(this::capitalize)
.collect(toMap(identity(),
String::length,
Integer::sum));
...
Terminating a Stream
Collect results into a HashMap, along with the length of (merged duplicate) entries
See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap
![Page 17: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/17.jpg)
17
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectGroupingBy() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
Map<String, Long> results =
...
.collect
(groupingBy
(identity(),
TreeMap::new,
summingLong
(String::length)));
...
Collect the results into a TreeMapby grouping elements according to name (key) & name length (value)
Terminating a Stream
See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy
![Page 18: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/18.jpg)
18
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectGroupingBy() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
Map<String, Long> results =
...
.collect
(groupingBy
(identity(),
TreeMap::new,
summingLong
(String::length)));
...
Terminating a Stream
groupingBy() partitions a stream via a “classifier” function, e.g., by the identity() function that always
returns its input argument
See docs.oracle.com/javase/8/docs/api/java/util/function/Function.html#identity
![Page 19: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/19.jpg)
19
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectGroupingBy() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
Map<String, Long> results =
...
.collect
(groupingBy
(identity(),
TreeMap::new,
summingLong
(String::length)));
...
Terminating a Stream
A factory supplier is used to create the type of map
![Page 20: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/20.jpg)
20
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectGroupingBy() {
List<String> characters =
Arrays.asList("horatio",
"laertes",
"Hamlet", ...);
Map<String, Long> results =
...
.collect
(groupingBy
(identity(),
TreeMap::new,
summingLong
(String::length)));
...
Terminating a Stream
A “downstream collector” defines a collector applied by the Java runtime to the results of an earlier collector
See docs.oracle.com/javase/tutorial/collections/streams/reduction.html
![Page 21: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/21.jpg)
21
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
Pattern.compile(",")
.splitAsStream
("horatio,Hamlet,...")
...
.collect
(groupingBy
(identity(),
TreeMap::new,
summingLong
(String::length)));
Terminating a Stream
Convert a string into a stream via regular expression splitting!
See docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#splitAsStream
![Page 22: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/22.jpg)
22
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
Pattern.compile(",")
.splitAsStream
("horatio,Hamlet,...")
...
.collect
(groupingBy
(identity(),
TreeMap::new,
summingLong
(String::length)));
Terminating a Stream
See docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy
Collect the results into a TreeMapby grouping elements according to name (key) & name length (value)
![Page 23: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/23.jpg)
23See docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
• a primitive value
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
...
long countOfNameLengths =
matchingCharactersMap
.values()
.stream()
.reduce(0L,
(x, y) -> x + y);
Terminating a Stream
Sum up the lengths of all character names in Hamlet
![Page 24: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/24.jpg)
24
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
• a primitive value
0 is the “identity,” i.e., the initial value of the reduction & the default result if there are no elements in the stream
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
...
long countOfNameLengths =
matchingCharactersMap
.values()
.stream()
.reduce(0L,
(x, y) -> x + y);
Terminating a Stream
![Page 25: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/25.jpg)
25
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
...
long countOfNameLengths =
matchingCharactersMap
.values()
.stream()
.reduce(0L,
(x, y) -> x + y);
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
• a primitive value
This lambda is the “accumulator,” which is a stateless function that combines two values into a single (immutable) “reduced” value
Terminating a Stream
![Page 26: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/26.jpg)
26
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
• a primitive value
There’s a 3 parameter “map/reduce” version of reduce() that’s used in parallel streams
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
...
long countOfNameLengths =
matchingCharactersMap
.values()
.parallelStream()
.reduce(0L,
(x, y) -> x + y,
(x, y) -> x + y);
See www.youtube.com/watch?v=oWlWEKNM5Aw
Terminating a Stream
![Page 27: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/27.jpg)
27
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
• a primitive value
There’s a sum() method that simplifies the use of reduce()
void runCollectReduce() {
Map<String, Long>
matchingCharactersMap =
...
long countOfNameLengths =
matchingCharactersMap
.values()
.stream()
.sum()
Terminating a Stream
See docs.oracle.com/javase/8/docs/api/java/util/stream/LongStream.html#sum
![Page 28: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/28.jpg)
28
• Other terminal operations returnthe result of a reduction operation, e.g.
• a collection
• a primitive value
Terminating a Stream
Intermediate operation (behavior f)
Output f(x)
Output g(f(x))
Intermediate operation (behavior g)
Terminal operation (behavior h)
…
Input x
collect() & reduce() terminal operations work seamlessly with parallel streams
parallelStream()
![Page 29: Overview of Java 8 Streams (Part 4) - Vanderbilt …schmidt/cs891f/2018-PDFs/08-Java...4 •Every stream finishes with a terminal operation that yields a non-stream result Intermediate](https://reader036.vdocuments.us/reader036/viewer/2022062916/5ebe3397edbe61408d5e0156/html5/thumbnails/29.jpg)
29
End of Overview of Java 8 Streams (Part 4)