Java-8 Streams

Reading Time: 3 minutes

Hi folks, In this blog we would talk about one of the features of Java 8 which is Streams. The java package contains classes to support functional-style operations on streams i.e. map, filter etc. Streams is not a data structure that stores something instead of it a way to flow data from source to destination with some intermediate operation in between. Let’s take an example first so that we can grasp concepts fast.

This image has an empty alt attribute; its file name is untitled-diagram-15.png

Let’s say, we have a collection of books Collection<Book> where Book class has two attributes writer and price and we want to obtain the sum of price’s where the writer is “Neil Chetan”. In order to obtain the result, we need to do some like –

int totalPrice =
                      .filter(b -> b.getWriter() == "Neil chetan")
                      .map(b -> b.getPrice())

The stream is a series of operations that can be Intermediate or terminal operation.

  • The Intermediate operations return a new stream as result and we can call multiple intermediate operations one after the other. The Intermediate operations are executed before terminal operation. These types of operation are always lazy in nature means they will not be executed until the result of a processing is needed.
  • The Terminal operation allows us to produce a final result from the remaining data. After applying this operation on the stream means that the stream has consumed. Computation on the stream pipeline is performed when the terminal operation is initiated.

Properties of Lambda

  • It’s functional in nature means if we apply streams on some data, results get some result, it doesn’t mean it will modify the source, rather it will create a new stream from the existing stream.
  • Intermediate operations are always lazy.
  • During the life of the stream, the element of the stream is only visited only once.

Stream creation

Let’s create a stream from Array of book –

private static Book[] arrayOfBook = {
    new Book("Jeff Bezos", 123.0), 
    new Book("Neil chetan", 245.0), 
    new Book("Mark Zuckerberg", 343.0),
    new Book("Bill Gates", 143.0)


We can also use the stream() method directly to convert into streams from the list.

private static List<Book> bookList = Arrays.asList(arrayOfBook);;

Stream operations

  • filter : It produces a new stream that contains the element which passes the predicate. i.e:
Integer[] bookPrice = { 100, 200, 300, 44 };
    List<Integer> totalPrice = Stream.of(bookPrice)
      .filter(e -> e >= 200)

Result – { 200, 300 }

  • map: It produces a new stream after applying a function to each element of the original stream.
List number = Arrays.asList(2,3,4,5)

Result: { 4, 6, 8, 10 }

  • forEach:  It is the simplest operation and looks the same as map but it’s a terminal operation, which means that after applying this operation we cannot use any other operations(the stream has been consumed).
  • flatMap : It’s a combination of flat and map functions.
List<List<Integer>> listOfList = Arrays.asList(
List<Integer> list = 
                                    .flatMap(list ->

Result : { 1, 2, 3, 4, 2, 1, 3 }

  • collect : The collect function is a terminal operation and convert the stream into some other collection or entity. i.e In the example we will convert stream to list.
List<Integer> IntSet = Stream.of(1,2,3,4,5)
              .map(x -> x+1)

Result : List(2, 3, 4, 5, 6 )

That’s pretty much it from the article. If you have any feedback or queries, please do let me know in the comments. Also, if you liked the article, please give me a thumbs up and I will keep writing blogs like this for you in the future as well. Keep reading and Keep coding.

This image has an empty alt attribute; its file name is footer-2-1.jpg

Written by 

Lokesh Aggarwal is a software Consultant trainee with 6 months of experience at Knoldus Inc.