Step 1 of 5 · Reading · ~3 min
Learn
Collections
Streams
You already process sequences with a loop, an if and an accumulator. Streams (Java 8+) describe the same work declaratively: say what happens to the data (keep these, transform those, combine the rest) and let the library run it. By the end of this lesson you can build a pipeline over an array or list, bridge between primitive and boxed streams, and turn a stream's result into a line of text.
A first pipeline
import java.util.Arrays;
int[] prices = {12, 7, 30, 7};
long pricey = Arrays.stream(prices) // source
.filter(p -> p > 10) // keep: 12, 30
.count(); // terminal: 2
A pipeline always has three parts:
- Source:
Arrays.stream(array),list.stream(),IntStream.rangeClosed(1, 5),Stream.of(...). - Intermediate operations, each returning a new stream so they chain:
filter(keep elements passing a test),map(transform each element),distinct,sorted,limit. - One terminal operation that produces the result:
sum(),count(),max(),collect(...),forEach(...),toArray().
Streams are lazy: intermediate steps do nothing until a terminal operation asks for the result, so a pipeline with no terminal operation never runs. A stream is also single use; reusing one throws IllegalStateException: stream has already been operated upon or closed. And a pipeline never changes its source: prices is untouched afterwards.
Lambdas and method references
p -> p > 10 is a lambda, an inline function: parameters, an arrow, a body. When a lambda only calls one existing method, a method reference is shorter: String::toUpperCase means s -> s.toUpperCase().
Two flavors of stream
Arrays.stream(int[]) gives an IntStream, a stream of primitive ints. It has numeric terminals like sum(), max() and average(). A stream built from an ArrayList<Integer> is a Stream<Integer>, a stream of boxed objects, and has none of those:
ArrayList<Integer> boxed = new ArrayList<>();
boxed.add(3);
boxed.add(1);
boxed.add(2);
boxed.stream().mapToInt(Integer::intValue).sum(); // 6: bridge to IntStream first
mapToInt converts to an IntStream, and boxed() goes the other way. An empty IntStream's sum() is simply 0.
Producing text from a stream
To build one string from the elements, convert them to strings and join:
import java.util.stream.Collectors;
import java.util.stream.IntStream;
String tags = IntStream.rangeClosed(1, 5)
.mapToObj(n -> "#" + n) // IntStream -> Stream<String>
.collect(Collectors.joining(",")); // "#1,#2,#3,#4,#5"
mapToObj turns each int into an object (here a String, by joining "#" and the number). Collectors.joining(sep) puts the separator between elements only, so there is no trailing separator to trim. The same shape works on words:
String[] drinks = {"tea", "coffee", "milk", "ale", "juice"};
String long4 = Arrays.stream(drinks)
.filter(w -> w.length() > 3)
.map(String::toUpperCase)
.sorted()
.collect(Collectors.joining(", ")); // "COFFEE, JUICE, MILK"
Order of stages matters
sorted() sorts whatever reaches it. Sorting before a map that squares negative numbers gives a different order than sorting after, because -9 sorts before 1 but its square 81 sorts after 1. Likewise distinct() removes duplicates of whatever it sees, so removing duplicates before or after a transformation can keep different numbers of elements. Read the pipeline top to bottom and say what the data looks like after each stage.
Remember the remainder rules
Inside a filter, Java's % keeps the sign of the left operand: -3 % 2 is -1. So n % 2 == 1 quietly rejects negative odd numbers; test oddness with n % 2 != 0.
Common mistakes
- Forgetting the terminal operation: the pipeline compiles and does nothing.
- Calling
sum()on aStream<Integer>: usemapToIntfirst. - Assuming a stage order that is not the one written, especially
sortedanddistinct. - Reusing a stream after a terminal operation.
Your exercise
Build one pipeline that takes a line of integers, keeps a subset, transforms them, tidies the result (duplicates, order) and prints it as a single line of text. The tests include negative odd numbers and pairs like -3 and 3, so the order of your stages is checked.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…