More about Streams- Functional Programming in JAVA 8- Part 10

You can think of a Stream as a new view of Collection. A Stream will always have a source, generally a Collection.
A Stream in JAVA 8 comprises of 3 different elements:-

  • source, basically a Collection.
  • operations that need to be performed on that Stream, like filter.
  • terminal operation,i.e. the end condition. Like forEach, this causes the Stream to do its thing. Unless you have a terminal operation the Stream doesn’t start.
public class StreamsExample1 {

	public static void main(String[] args) {
		List<Person> people=Arrays.asList(
				new Person("Charles","Dickens",60),
				new Person("Lewis","Carroll",42),
				new Person("Thomas","Carlyle",51),
				new Person("Charlotte","Bronte",45),
				new Person("Matthew","Arnold",39));

                people.stream()
                .filter(p->p.getFirstName().startsWith("C"))
                .forEach(p->System.out.println(p.getFirstName());
        }
}

Now what if we do just below:-

Stream<Person> stream=people.stream();

So what does people.stream(); returns, it just returns a view of Collection, a way of looking into our people Collection. Note that just by doing above nothing happens, no iteration. It’s like building a conveyor belt and just putting the Collection elements on it, but the conveyor belt hasn’t started yet.
But when we do below what happens?

people.stream()
.filter(p->p.getFirstName().startsWith("C"));

We are just setting the operation on the Stream. It’s like asking a worker to be positioned at the assembly line. Not that assembly line/conveyor belt has not started even yet.
Let’s ad a terminal operation.

people.stream()
.filter(p->p.getFirstName().startsWith("C"))
.count();

SO, this returns the count of elements in the Stream, this makes a Stream end. You can’t have a method after terminal operation. Actually, this terminal operation starts the Stream & all the Collection elements will have to go through the filter. We can also assign a local variable to above instruction.

long count=people.stream()
          .filter(p->p.getFirstName().startsWith("C"))
          .count();

Stream is basically a way of taking iteration out of your control, it’s not an external iteration(like for loop), it’s an internal iteration. JAVA Runtime is doing iteration & we are just doing operations on that iteration.
You must have noticed as of now that each of the operations over Streams takes in a lambda expression. these lambda expressions declare what needs to be happen with each element of Collection on Stream. We all know that one of the advantage of using lambda expressions is that they enable parallel programming. Advantage is you can have different portions of Collections handled in different processors.
So, if you have multicore processors you can have portions of a huge collection be executed different things in different cores. Think of it as a separate assembly lines. And one portion of a Collection(say 1st 2 elements) go to different assembly line & left elements go to another assembly line. And the way to do this is using another method on Collection called parallelStream().

long count=people.parallelStream()
          .filter(p->p.getFirstName().startsWith("C"))
          .count();

parallelStream() is like a Stream, but it could potentially return a parallel Stream if it feels that multiple cores would be used to make this faster. It could potentially split the Collection into multiple Streams and do the exact said things(results not gonna change), but it could potentially do things in parallel. So, this is one of the major advantage of functional programming model that lambdas enable.

So, it’s time to wrap up this basic introduction to Lambda expressions and Streams of JAVA 8.
So let’s summarize as to what Lambda expressions of JAVA 8 promises us:-

  • Enables Functional programming. It makes us think functions as entities.
  • Readable and concise code.
  • Easier to use APIs & libraries. It made us get rid of JAVA 7 way of passing behaviour to APIs by creating classes or objects.
  • Enables support for parallel programming.