Streams in Java 8 are a new language feature that enables you to write functional operations on streams of elements. Okay, so what are streams of elements? Well, let’s step back for a minute.

Most Java applications make heavy use of collections such as List and Map. These collections contain zero or more elements. Let’s say you want to loop through a List of Strings.

Given the following ArrayList of Strings:

1
2
3
List<String> strings = new ArrayList<String>();
strings.add("hello");
strings.add("world");



Traditionally you would do something like this:

1
2
3
for(String s : List<String> strings) {
    System.out.println(s);
}



Which produces the following output to the console:

1
2
hello
world



Let’s see what this looks like using Streams:

1
2
strings.stream()
    .forEach(System.out::println);



By using the Stream capabilities in Java 8 your List of Strings is transformed into a sequence of elements or Stream of elements which you can then operate on. The Stream is not actually stored anywhere but rather computed on demand using zero or more Intermediate Operations and a final terminal operation. In the example above the terminal operation is forEach.

Here’s another example using an Intermediate Operation. Let’s say you want to reverse sort the List of Strings so they instead output:

1
2
world
hello



To do this we need an intermediate Sort Operation sorted:

1
2
3
strings.stream()
    .sorted((a, b) -> b.compareTo(a))
    .forEach(System.out::println);



Streaming in Java 8 makes Sorting Collections a simple Intermediate Operation whereas in earlier versions of Java you would have to either write a custom Comparator class or provide an anonymous Comparator.

By adding an Intermediate Operation to your Stream operation you are effectively building a Pipeline of operations which will be processed once the Terminal Operation is executed. Each Intermediate Operation is processed one by one for example, let’s say you want to print only the first element of your sorted list. You could add the limit Operation to your Pipeline:

1
2
3
4
strings.stream()
    .sorted((a, b) -> b.compareTo(a))
    .limit(1)
    .forEach(System.out::println);



This will of course output the following:

1
world



What happens if you add the limit Operation before the sorted Operation?

This will end up with the following:

1
hello



What is going on? Remember, you are building a Pipeline that operates on your stream of elements. So when you use the limit operation before the sort then you have effectively limited your stream to one single element and performed a sort against one element!

Take a look at the Java Docs for more information and have fun Streaming! Java 8 Streams