A sequence of elements supporting sequential and parallel aggregate operations is called as Streams.

int sum = widgets.stream()
                      .filter(w -> w.getColor() == RED)
                      .mapToInt(w -> w.getWeight())
                      .sum();

Stream operations are composed into a stream pipeline. A stream pipeline consists of a source (which might be an array, a collection, a generator function, an I/O channel, etc), zero or more intermediate operations (which transform a stream into another stream, such as filter(Predicate)), and a terminal operation (which produces a result or side-effect, such as count() or forEach(Consumer)).

Streams are lazy; computation on the source data is only performed when the terminal operation is initiated, and source elements are consumed only as needed,

Features of Java stream

  • Streams not make changes in the original data structure, it only provide the result as per the pipelined methods.
  • A stream is not a data structure ,it takes input from the Collections, Arrays or I/O channels.
  • Streams are lazy; computation on the source data is only performed when the terminal operation is initiated, and source elements are consumed only as needed.
  • A stream should be operated only once.
  • Most streams are backed by collections, arrays, or generating functions, which require no special resource management.
  • Stream pipelines may execute either sequentially or in parallel.
  • Streams are created with an initial choice of sequential or parallel execution.
  • Internal iteration is supported in streams. We do not have to declare steps for iteration while using streams.

Consider we have the Employee example.. we have Employee with set of required details as a list. and we need to take out a list of customer which have some criteria,

package com.asysncster.streams;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class Employee {

	private String customerId;
	private String name;
	private int age;
	double salary;
}
List<Employee> employees = new ArrayList<>();
 employees.add(new Employee ("a55ev314","Sara", 20,4500.00)); 
 employees.add(new Employee ("a55ed312","Josh", 35, 5600.50));
 employees.add(new Employee ("at5ed314","Harry", 26,2300.25));
 employees.add(new Employee ("a55ed314","Joseph", 30,7600.75));

Before Java8 , we need to use the traditional for loop. as below.

Iterator<Employee> employeeList = employees. iterator();
    	List<Double>  salariesList = new ArrayList<>();
    	while( employeeList.hasNext()) {
    	Employee emp = employeeList.next();
    	if( emp.getAge()>25)
    		salariesList.add(emp.getSalary());
    	}
    	System.out.println("salariesList for employee where age is >25 : "+salariesList);

We need to do the steps as follows:

  1. First we have to create an iterator object.
  2. Then check if iterator can travel (verify if collection is not null) and fetch a particular item.
  3. Once we get true from step 2, we can use next() to go ahead and extract the item.
  4. After getting value from step 3, only can we do operation that we need to perform with value from collection.

So we drawbacks using this approach as below:

  • If we work with multiple collections, these steps have to be performed for all those collections as well.
  • This will result in repetition of code.
  • When we operate on collection using an iterator, we can perform operation on elements only in sequential manner.
  • Parallel operations not supported, which will lead to performance issue in handling large collections.
  • Readability is relatively very poor.

Using Java8 Streams, we can simplify the given code as below:

What is stream pipeline ?

When intermediate operations being performed on stream, it take elements from an input stream and produce a output stream.

This is one chain of operation having two streams.

When two or more of this chains are connected , they form a stream pipeline. Streams connect through these chain of operations and form a stream pipeline

List<Double>salariesList1=  employees.stream().filter(em->em.getAge()>25).map(em->em.getSalary()))).collect(Collectors.toList()));

		System.out.println("salariesList for employee where age is >25 : "+salariesList1);

In this Article we have seen, What is Streams in Java8, Streams features, what is stream pipeline.

Streams in Java – Asyncster

One thought on “Streams in Java – Asyncster

  • 09/27/2022 at 1:28 AM
    Permalink

    Hi there i am kavin, its my first time to commenting anywhere, when i read this article
    i thought i could also make comment due to this brilliant post.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *