ICS 45J: Programming in Java
Lecture 10-2
Stream Processing, Part 2
Course Wrap-Up
Emily Navarro
PART 1
Canvas Participation Quiz
Lecture 10-2: Lecture 10-1
Review
Text questions to (562) 684-8307
Last Time
• A stream is an immutable sequence of values that are processed lazily
• The Stream.of static method and the stream methods of collection classes yield
streams
• You can transform streams into a form from which you can collect results using the
map and filter methods
• A lambda expression consists of one or more parameter variables, an arrow ->, and
an expression or block yielding the result
• The Optional class is a wrapper for objects that may or may not be present
Text questions to (562) 684-8307
PART 2
Learning Objectives
• To be able to develop filter/map/reduce strategies for solving
data processing problems
• To convert between collections and streams
• To use function objects for transformations and predicates
• To work with the Optional type
Text questions to (562) 684-8307
Agenda
• Other Terminal Operations
• Primitive-Type Streams
• Grouping Results
• Course Wrap-Up
Text questions to (562) 684-8307
Agenda
• Other Terminal Operations
• Primitive-Type Streams
• Grouping Results
• Course Wrap-Up
Text questions to (562) 684-8307
Other Terminal Operations
• findAny is like findFirst, but returns any match, not necessarily the first one, and is
faster on parallel streams
result = words
.parallel()
.filter(w -> w.length() > 10)
.filter(w -> w.endsWith("y"))
.findAny()
.orElse("");
• max/min require a comparator and return an Optional (since the input may be empty):
Optional<String> result = words.max((v, w) -> v.length() - w.length());
• allMatch/anyMatch/noneMatch check a predicate:
boolean result = words.allMatch(w -> w.contains("e"));
// result is true if all words contain the letter e
Text questions to (562) 684-8307
Canvas Participation Quiz
Lecture 10-2: Other
Terminal Operations
Text questions to (562) 684-8307
PART 3
Agenda
• Other Terminal Operations
• Primitive-Type Streams
• Grouping Results
• Course Wrap-Up
Text questions to (562) 684-8307
Primitive-Type Streams
• Inefficient to have streams of number wrappers such as
Stream<Integer>
• For example, numbers.map(x -> x * x) requires unboxing
and boxing for each element
• IntStream, LongStream, DoubleStream work with int,
long, double values without boxing
Text questions to (562) 684-8307
Creating Primitive-Type Streams
• Can create from individual numbers, or an array:
IntStream stream = IntStream.of(3, 1, 4, 1, 5, 9);
int[] values = {3, 1, 4, 1, 5, 9};
stream = IntStream.of(values);
• range yields a contiguous range of integers:
IntStream stream = IntStream.range(a, b);
// Stream contains a, a + 1, a + 2, ..., b - 1
• Random generator yields infinite stream of random numbers:
Random generator = new Random();
IntStream dieTosses = generator.ints(1, 7);
Text questions to (562) 684-8307
Mapping Primitive-Type Streams
• IntStream.map with an int -> int function yields another IntStream
IntStream stream = IntStream.range(0, 20)
.map(n -> Math.min(n, 10));
// A stream with twenty elements 0, 1, 2, ..., 9, 10, 10, ..., 10
• When the function yields objects, use mapToObj:
String river = "Mississippi";
int n = river.length();
Stream<String> prefixes = IntStream.range(0, n)
.mapToObj(i -> river.substring(0, i));
// "", "M", "Mi", "Mis", "Miss", "Missi", ...
• Also have mapToDouble, mapToLong if the function yields double, long values
• Think of IntStream.range(a, b).mapXXX as an equivalent of a for loop that yields a
value in each iteration
• Use mapToInt/mapToLong/mapToDouble with streams of objects when the map function
yields primitive type values
Text questions to (562) 684-8307
Processing Primitive-Type Streams
• Stream methods for primitive-type streams have modified
parameters/return types
• For example, IntStream.toArray returns an int[] and
doesn’t require a constructor
• Four additional methods: sum, average, max, and min
(without comparators)
• Last three return
OptionalInt/OptionalLong/OptionalDouble
double average = words
.mapToInt(w -> w.length())
.average()
.orElse(0);
Text questions to (562) 684-8307
Canvas Participation Quiz
Lecture 10-2: Primitive-
Type Streams
Text questions to (562) 684-8307
PART 4
Agenda
• Other Terminal Operations
• Primitive-Type Streams
• Grouping Results
• Course Wrap-Up
Text questions to (562) 684-8307
Grouping Results
• So far, results were either a value or a collection
• Sometimes, we want to split a result into groups
• Example: Group all words with the same first letter together
• Use:
stream.collect(Collectors.groupingBy(function))
• function produces a key for each element
• The result is a map
• Map values are collections of elements with the same key
Map<String, List<String>> groups = Stream.of(words)
.collect(Collectors.groupingBy(
w -> w.substring(0, 1))); // The function for extracting the keys
• groups.get(“a”) is a list of all words starting with a
Text questions to (562) 684-8307
Processing Groups
• Nice to split result into groups
• Even nicer: Can process each group
• Pass a collector to Collectors.groupingBy
• Example: Group into sets, not lists:
Map<String, Set<String>> groupOfSets = Stream.of(words)
.collect(Collectors.groupingBy(
w -> w.substring(0, 1), // The function for extracting the keys
Collectors.toSet())); // The group collector
• The groupingBy collector collects the stream into groups
• The toSet collector collects each group into a set
Text questions to (562) 684-8307
Collecting Counts and Sums
• Use Collectors.counting() to count the group values:
Map<String, Long> groupCounts = Stream.of(words)
.collect(Collectors.groupingBy(
w -> w.substring(0, 1),
Collectors. counting( )));
• groupCounts.get(“a”) is the number of words that start with an a
• To sum up some aspect of group values, use summingInt, summingDouble,
and summingLong:
Map<String, Long> groupSum = countries.collect(
Collectors.groupingBy(
c -> c.getContinent(), // The function for extracting the keys
Collectors.summingLong(
c -> c.getPopulation()))); // The function for getting the summands
• groupSum.get(“Asia”) is the total population of Asian countries
Text questions to (562) 684-8307
Collecting Average, Minimum, Maximum
• The Collectors methods averagingInt, averagingDouble, and
averagingLong work just like summingXxx
• Return 0 for empty groups (not an Optional)
• Average word length grouped by starting character:
Map<String, Double> groupAverages = Stream.of(words)
.collect(Collectors.groupingBy( w ->
w.substring(0, 1),
Collectors.averagingInt(String:: length) ));
• maxBy, minBy use a comparison function and return Optional results:
Map<String, Optional<String>> groupLongest = Stream.of(words)
.collect(
Collectors.groupingBy(
w -> w.substring(0, 1), // The function for extracting the keys
Collectors.maxBy(
(v, w) -> v.length() - w.length()))); // The comparator function
Text questions to (562) 684-8307
Demo: GroupDemo.java
Text questions to (562) 684-8307
Canvas Participation Quiz
Lecture 10-2: Grouping
Results
Text questions to (562) 684-8307
PART 5
Agenda
• Other Terminal Operations
• Primitive-Type Streams
• Grouping Results
• Course Wrap-Up
Text questions to (562) 684-8307
Overall Course Goals
• Build upon your fundamental programming concepts and
skills
• Learn the Java language
• Construct programs for varied problems and environments
• Build a solid foundation for future ICS courses and for your
career
Text questions to (562) 684-8307
Course Learning Objectives
• Implement Java programs using objects, customized classes,
variables, decisions, loops, arrays, maps, Java collections, stream
processing, and recursion
• Design Java classes and programs using good object-oriented
design principles
• Understand and apply inheritance, interfaces, and encapsulation
to your Java programs
• Write Java programs that are robust and handle exceptions
correctly
• Implement simple graphical user interfaces using the Swing
framework
Text questions to (562) 684-8307
Newer (Optional) Java Features Not Covered
• var keyword
• java.util.random.RandomGenerator
• switch expressions
• Variable length method argument lists (using …)
• Records
• Sealed classes and interfaces
• Multi-catch
• Assertions
• Unnamed variables
• Variable number of args to a method
• Wildcard type arguments
• JShell
• Module system
Further Reading
Expand your Java skills
• Expand on some of the labs:
• Add more functionality
• Add a GUI
• Make it fetch some data over the Internet
• Make it store data in a database
• Make it into a web app (https://spring.io/projects/spring-boot)
• Make it into an Android app (https://developer.android.com)
• Useful Java links: https://github.com/Vedenin/useful-java-
links?tab=readme-ov-file
Canvas Participation Quiz
Lecture 10-2: Reflection /
Advice
Text questions to (562) 684-8307
Summary
• A terminal operation triggers the lazy operations on a stream and
yields a non-stream value
• IntStream, LongStream, and DoubleStream contains
values of primitive types
• Using grouping collectors, you can group together elements with the
same key
• Congratulations on making it through ICS 45J! Be proud of yourself,
and the learning you have accomplished.
• Have a great break!
Text questions to (562) 684-8307