Stream intermediate operations

This example will show various code snippets to demonstrate stream intermediate operations. Intermediate operations return another Stream which allows you to call multiple operations in a form of a query. Intermediate operations do not get executed until a terminal operation is invoked as there is a possibility they could be processed together when a terminal operation is executed.


Stream.filter operation will return a new stream that contains elements that match its predicate. Below we will use a lambda expression to create a java.util.function.Predicate that will check if the integer is less than three. The terminal Stream.count operation will return the number of elements in the stream.

public void intermediate_filter() {

    long elementsLessThanThree = Stream.of(1, 2, 3, 4)
            .filter(p -> p.intValue() < 3).count();

    assertEquals(2, elementsLessThanThree);

map will transform the elements elements in a stream using the provided java.util.function.Function. A function is a method that accepts an argument and produces a result. They are commonly used for transforming collections and can be seen in the transforming a list to a map example.

In the snippet below we will create a function using a lambda expression that will replace any null strings in the stream with [unknown].

public void intermediate_map() {

    List<String> strings = Stream.of("one", null, "three").map(s -> {
        if (s == null)
            return "[unknown]";
            return s;

    assertThat(strings, contains("one", "[unknown]", "three"));



Stream.flatmap will transform each element into zero or more elements by a way of another stream. To demonstrate, we pulled code snippet from how to count unique words in a file example. Using java 7 file api, we will read all lines from a file as a Stream. Then calling Stream.flatmap we will break the line into words elements. If we had a line made up of "the horse was walking down the street", this line would be broken into ["the", "horse", "was", "walking", "down", "the", "street"]. Calling the the Stream.distinct method will find all unique occurrences of words.

public void count_distinct_words_java8() throws IOException {

    File file = new File(sourceFileURI);

    long uniqueWords = java.nio.file.Files
            .lines(Paths.get(file.toURI()), Charset.defaultCharset())
            .flatMap(line ->" ."))).distinct()

    assertEquals(80, uniqueWords);


The Stream.peek is extremely useful during debugging. It allows you to peek into the stream before an action is encountered. In this snippet we will filter any strings with a size of great than four then call the peek at the stream before the map is called. The peek operation will print out the elements of 'Badgers', 'finals' and 'four'.

public void intermediate_peek() {

    List<String> strings = Stream.of("Badgers", "finals", "four")
            .filter(s -> s.length() >= 4).peek(s -> System.out.println(s))
            .map(s -> s.toUpperCase()).collect(Collectors.toList());

    assertThat(strings, contains("BADGERS", "FINALS", "FOUR"));


Stream.distinct will find unique elements in a stream according to their .equals behavior. A use case to use distinct is when you want to find the distinct number of words in a file.

public void intermediate_distinct() {

    List<Integer> distinctIntegers = IntStream.of(5, 6, 6, 6, 3, 2, 2)

    assertEquals(4, distinctIntegers.size());
    assertThat(distinctIntegers, contains(
            5, 6, 3, 2));



The Stream.sorted method will return a stream sorted according to natural order. Below, we will create a stream of ints then calling the sort which will return the numbers in ascending order.

public void intermediate_sorted() {

    List<Integer> sortedNumbers = Stream.of(5, 3, 1, 3, 6).sorted()

    assertThat(sortedNumbers, contains(1, 3, 3, 5, 6));


Stream.limit is a useful technique to limit the number or truncate elements to be processed in the stream. Similar to limit elements in a list, we can perform the same behavior within a stream as shown below.

public void intermediate_limit() {

    List<String> vals = Stream.of("limit", "by", "two").limit(2)

    assertThat(vals, contains("limit", "by"));