Introduction to Stream

Author      Ter-Petrosyan Hakob

Streams let you work with collections more simply than loops. With a stream, you tell Java what you want to do, not how to do it. Java then chooses the best way to run your code.

When you work with a collection, you often loop through its items and do something with each one. For example, imagine you have a list of words and you want to count how many have more than 8 letters.

List<String> words = List.of(
    "programming", 
    "java",
    "hibernate", 
    "code",
    "development",
    "test",
    "bug",
    "fix",
    "application",
    "data"
);

int count = 0;
for (String word : words) {
    if (word.length() > 8) {
        ++count;
    }
}

System.out.println("Words with more than 8 letters (using loop): " + count);

long streamCount = words.stream()
    .filter(word -> word.length() > 8)
    .count();

System.out.println("Words with more than 8 letters (using stream): " + streamCount);

With a stream, you do not need to read a long loop to see how filtering and counting work. The method names (for example, filter() and count()) show exactly what the code does. In a loop, you must write every step in order. A stream, however, can run those steps in any order it wants, as long as it gives the correct result.

At first glance, streams look like collections—you can change data and get results. But streams behave in different ways:

Let’s look at the example again. We use stream() or parallelStream() on the words list to make a stream. Then:

This pattern—making a stream, transforming it, and then getting a result—is very common. You can think of it as three steps: