Java Streams
Java Streams: What are
they (not)?
●
○
●
What is this… “functional”
programming?
● methods
○
A Functional
Programming Parable 1
2
But what is a “Stream”?
●
●
○
○
○
●
●
How to make streams?
●
○ import java.util.stream.*
●
○ String[] menuItemNames = {"Grits", "Pancakes", "Burrito"};
Stream.of(menuItemNames); // returns a stream, so needs “=” before it
○ Stream.of("Hedgehog", "Kitten", "Fox"); // arbitrary argument count
● stream() Collection
○ List<String> menuItemNameList = Arrays.
asList(menuItemNames);
○ menuItemNameList.stream();
●
forEach
● Intuition →
●
●
● Stream.of(users).forEach(e -> e.logOut());
○
forEach
●
○ Stream.of("hello", "world").forEach(word -> System.out.println(word));
○
●
○ Stream.of("hello", "world").forEach(System.out::println);
○ class::method
Some More Common Stream Operations
map filter sorted
limit distinct collect
collect (Basics)
●
●
○ Stream<Integer> stream = Arrays.asList(3,2,1,5,4,7).stream();
●
○ List<Integer> list = stream.collect(Collectors.
toList());
○ Set<Integer> list = stream.collect(Collectors.
toSet());
●
○ Collectors.groupingBy( ) Collectors.reducing( );
map
● Intuition →
●
T → → K
Stream<T> .map ( ) → Stream<K>
●
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
map
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
map
List<Integer> numbersTripled =
→
→numbers.stream().map(x -> x*3).collect(toList());
3
map
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
→
→
3 6
map
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
→
→
3 6 9
map
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
→
→
3 6 9 12
map
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
→
→
3 6 9 12 15
map
List<Integer> numbersTripled =
numbers.stream().map(x -> x*3).collect(toList());
→
→
3 6 9 12 15 18
map
●
.map(x -> x/ 2)
●
.map(x -> {
… some code …
return something;
})
●
.map(String::toUpperCase)
filter
● Intuition →
●
●
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2000
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2000
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2005
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2010
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2015
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2020
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
2025
y != 2020
y y != 2020
filter
List<Integer> goodYears = years
.stream().filter(y -> y != 2020).collect(toList());
y != 2020
filter
●
○ List<Integer> leapYears =
years.stream().filter(y -> {
if (y % 400 == 0) return true;
if (y % 100 == 0) return false;
if (y % 4 == 0) return true;
return false;
}).collect(toList());
●
● Predicate<T> boolean test(T t)
sorted
var numbers = Arrays.asList(3, 2, 1, 5, 4, 7);
numbers.stream().sorted().forEach(System.out::println);
distinct
var numbers = Arrays.asList(3,3,1,1,4,7,8);
numbers.stream().distinct().forEach(System.out::println);
limit
var numbers = Arrays.asList(3,2,2,3,7,3,5);
numbers.stream().limit(4).forEach(System.out::println);
collect (Reductions)
● Stream.collect()
●
●
reduced aggregate vote count
● reduced
average height
● reduced maximum
(oldest) age
collect (Reductions)
●
List<Integer> teamHeights = List.of(73, 68, 75, 77, 74);
● Collectors. reducing
●
int totalHeight = teamHeights.stream().collect(
Collectors.reducing(0, (accumulator, curr) -> (accumulator + curr))
);
● System.out.println(totalHeight);
○ 367
collect (Reductions)
Collectors.reducing(0, (accumulator, curr) -> (accumulator + curr))
[ 73, 68, 75, 77, 74 ]
Accumulator value: 0
Current stream element: 73
New accumulator value: 73
collect (Reductions)
Collectors.reducing(0, (accumulator, curr) -> (accumulator + curr))
[ 73, 68, 75, 77, 74 ]
Accumulator value: 73
Current stream element: 68
New accumulator value: 141
collect (Reductions)
Collectors.reducing(0, (accumulator, curr) -> (accumulator + curr))
[ 73, 68, 75, 77, 74 ]
Accumulator value: 141
Current stream element: 75
New accumulator value: 216
collect (Reductions)
Collectors.reducing(0, (accumulator, curr) -> (accumulator + curr))
[ 73, 68, 75, 77, 74 ]
Accumulator value: 216
Current stream element: 77
New accumulator value: 293
collect (Reductions)
Collectors.reducing(0, (accumulator, curr) -> (accumulator + curr))
[ 73, 68, 75, 77, 74 ]
Accumulator value: 293
Current stream element: 74
New accumulator value: 367 (Final result)
Some More Common Stream Operations
count skip findFirst
toArray flatMap peek
Restaurant Example
Customer asks:
Stream Stream Stream Stream Stream
Collection Stream filter map sorted distinct limit
Streams in code...
●
●