A terminal operation finishes a Java Stream pipeline: it triggers evaluation and creates a final result. Until then, intermediate operations such as filter(), map(), and sorted() only describe work to perform. Common terminal operations include count(), toArray(), collect(), and toList(). section 9.2
Filtering requires a finishing operation
Calling filter() alone neither filters a list nor changes it. Keep the result of a terminal operation when a new list is wanted: stringList = stringList.stream() .filter(str -> !str.isEmpty()) .collect(Collectors.toList()); When mutation is intended and the list is mutable, removeIf(String::isEmpty) changes it in place instead. section 2.11
Treat intermediate functions as free of important side effects. Stream implementations may optimize pipeline stages, evaluate only the elements needed, or run work concurrently with parallelStream(). A side effect in filter(), map(), or peek() can therefore be skipped, reordered, repeated unexpectedly, or race with other work. Use collectors such as partitioningBy() when the real goal is to split elements into groups. section 9.2 section 9.13
Partition instead of mutating from filter
Rather than add rejected values to another list inside filter(), collect both groups explicitly: Map<Boolean, List<String>> partitions = list.stream() .collect(Collectors.partitioningBy(s -> s.contains("needle"))); This makes the final result, rather than an intermediate side effect, carry both partitions. section 9.2
A terminal operation also consumes a stream. Do not call count() and then anyMatch() on the same Stream, or retain one stream for repeated loop iterations; later use can fail with IllegalStateException. Reassign a stream when an intermediate operation returns a replacement pipeline, create a fresh stream from the source, or collect elements into an intermediate collection when multiple passes are necessary. section 9.3 section 9.13
stringList = stringList.stream().filter(str -> !str.isEmpty())
.collect(Collectors.toList());
stringList = stringList.stream().sorted()
.collect(Collectors.toList());
Compare ignored filtering and sorting pipelines with versions that finish via collect() and retain the resulting lists. section 2.11


