Sunday, June 12, 2016

An itroduction to Java 8 Streams

As now a days CPUs are getting more and more cheaper because of huge amount  of development  in hardware front, Java8 exploits these features of multi core CPU and is in process of continuously  introducing more and more support for parallelism.As a result we are seeing new features like fork-join framework and java streams etc.Here we discuss what is java stream and it's usefulness in parallel processing.

There are 3 series of posts about java stream in my blog.Here we will cover in detail with real world examples of java stream.Also I have mentioned some the  code segments the same way as I have used in one of my projects.when I started to study about Java stream I was confused it with java inputstream and outputstream, but they are completely different.

In this series you will learn what is java stream and where to use it and different kind of stream operations.We will learn about sequential  and parallel stream and important operations like map,flatmap,reduce,collect etc. on it.

If you are not familiar with java 8 Lambda expression ,functional interface and method  reference I request to visit my series Java 8 Lambda expression first.
Let's start our discussion with java8 streams.

Aggregate operations:

But first let's define what is aggregate operations.
An aggregate operation computes a single value from a set of values.Common aggregate functions are:
  • Average() (i.e., arithmetic mean)
  • Count()
  • Maximum()
  • Median()
  • Minimum()
  • Mode()
  • Sum()
 Here observe that this functions are applied on a set of values and give us a single value.The result of aggregate functions may be an object or a primitive type or empty.

Stream:


A stream is a sequence of elements which supports  sequential and parallel  aggregate operations.Now let's discuss some of the features of stream.Here we use lambda expression extensively.So if you have no idea about Lambda expression Please visit the Lambda Expression series.

Features Of Stream:


  • 1.A stream has no storage; it does not store elements. A stream pulls elements from a data source on-demand(lazily) and passes them to a aggregate operation for processing.Now if you are thinking what is the source of the stream?The answer is it can be collection but not always.It can be any data source like a generator function or an I/O channel or a data structure.

  • 2.A stream can represent a group of infinite elements.A stream pulls its elements from a data source that can be a collection, a function that generates data, an I/O channel, etc. Because a function can generate an infinite number of elements and a stream can pull data from it on demand, it is possible to have a stream representing a sequence of infinite data elements.

  • 3.A stream support  internal iteration, so no need to use for each loop or an iterator for accessing elements.External iteration like for each loop or an iterator usually gives the elements in sequential or insertion order.That is only single thread can consume the elements.But always it is not desired.Stream is there to help us. They are designed to process their elements in parallel without our notice. It does not mean streams automatically decide on our behalf when to process  elements in sequential or parallel.We have to tell a stream that we want  parallel processing and the stream will take care of it. In background stream uses Fork/Join framework to achieve parallel processing.Although stream support internal iteration ,but still they provide an iterator() method that returns an Iterator to be used for external iteration of its elements if necessary,but rarely used.

  • 4.Two types of operations are supported by stream.We call it as lazy (intermediate) operation and eager(terminal) operation.When a eager operation is called on the stream ,then only lazy operation process the elements of the stream.Let's take a problem to solve using java stream.Suppose we have a list of 10 integers and we want the sum of the square of even integers. Let's see the digram below.We write the code following the below digram.

Datasource----------Stream---------Filter-----Stream -----map------Stream-------reduce

List numberList = Arrays.asList(1, 2, 3, 4, 5,6,7,8,9,10);
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.reduce(0, Integer::sum);


Here numberList is our data source.Then we apply stream on it,it gives us a stream.Then we apply Filter on it to find only even numbers.The filter operation provides us another stream of even numbers.Then we apply map on that stream.Then it gives us a stream of square of numbers.Then we apply reduce on this stream and find the sum of the numbers on the stream.
Here reduce is the terminal operation and filter and map are intermediate operations.This process in which one stream provides another stream and this stream provides a next stream etc. is called stream pipelining.

  • 5.Stream does not remove the elements from the data source  it only reads them.

  • 6.A sequential stream can be transformed into a parallel stream by calling the parallel() method on the created stream.

  • 7.We can find the stream related interfaces and classes are in the java.util.stream package.Please follow the digram for stream  related interfaces.

                                 AutoClosable
                                           |
                                           |
                                           |
BaseSteam   <T, S extends BaseStream<T, S>>
     |                           |                   |                        |
     |                           |                   |                        |
     |                           |                   |                        |
IntStream    LongStream    DoubleStream  Stream

To work with elements of reference type stream interface is there ,but to work elements of primitive types IntStream,LongStream and DoubleStream interfaces are available.

Methods common to all types of streams are declared in the BaseStream interface.Like sequential,parallel,isParallel and unordered etc.And methods related to intermediate and terminal operations  are declared in Stream interface.

In the second part of this series we will see the use of the stream operations with example.










No comments:

Post a Comment