Java 8 Stream API Part 1

In Java 8, streams allow you to process data in a declarative style as most of the stream methods based on functional interfaces. The stream operations can be done in both parallel and sequential ways. All the stream operations are on demand.

Why Stream API introduced in Java 8?

To understand this you have to understand below example. If you have to find even elements from a list of integers.


List<Integer> list = Arrays.asList(10,7,4,11);

List<Integer> evenList = new ArrayList&lt;&gt;();

for(Integer n : list){

if(n%2==0){

evenList.add(n);

}

}

The code seems fine and works well. But there are some issues within this code. Lets understand here.

  1. Here we are dealing with iterations using external iterator. Some programmers feels that we have complete control using external iterator then what the issue with is. To get this control, programmer needs to pay their lots efforts which is really not required.
  2. Need to do lots of code for making computation over collection.
  3. Here the flow is sequential.

All the above issues have resolved by Java 8 Stream API.

Stream Vs Collection

Collection internally usages some data structure to store the elements while stream works on the collection or array to do computation, it does not have any data structure for storing the results. Stream does not modify the collection while doing operations. Stream API provides internal iteration and other useful methods to perform other computation operations over the collection. Stream operations are lazy they don’t do anything until demanded means any terminal operation performed.

Benefits of Stream API

  1. A stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations.
  2. Manipulate flows of data in declarative way
  3. Compute data in parallel fashion without writing any explicit threading.
  4. Computation on demand, whenever a terminal operation invoked all the intermediate operations are being executed.
  5. Stream is consumable means cannot be reused once terminal operation invoked.

Major Functional Interfaces Used By Stream API

The Stream API is packaged under java.util.stream with several interfaces and classes. Here are the some major functional interfaces which are defined under java.util.function used by Stream API.

  1. Predicate
  2. Function.
  3. Consumer
  4. Supplier
  5. BiPredicate
  6. BiFunction
  7. BiCosumer

Read More

As they are functional interfaces, so can be used in lambda expressions.

Predicate

It is a functional interface with method named test(T t) and returns boolean value.


@FunctionalInterface

public interface Predicate<T>{

boolean test(T t); }

Example Of Predicate

 
Predicate<Integer> evenChecker = n->n%2==0;
boolean isEven = evenChecker.test(10); 

Function

It represents a function that accepts one argument and produces a result.


@FunctionalInterface

public interface Function<T,R>{

R apply(T t)

}

Example of Function

 
Function<Integer,Integer> squareFunc = (n)->n*n; 
int squarOfNum = squareFunc.apply(10);

Consumer

It represents an operation that accepts a single input argument and returns no result.

@FunctionalInterface
public interface Consumer<T>{
  void accept(T t)
}

Example of Consumer


Consumer<Integer> integerConsumer = System.out::println; //Method Reference

integerConsumer.accept(10);// it will print the number of console

Supplier

It represents an operation to return values and acts as supplier.

@FunctionalInterface
public interface Supplier<T>{
 T get();
}

Example Of Supplier


Supplier<Double> doubleOfStrings = ()-> Math.random();

BiPredicate

BiPredicate takes two input and return a boolean value.

public interface BiPredicate<T,U>{
boolean test(T t, U u);
}

Example Of BiPredicate

Here we are checking for equality of two objects using BiPredicate. Assuming we have a Customer class with field id and name. For this you need to override the equals() method in Customer class.

 BiPredicate<Customer,Customer> equalChecker = (c1,c2)-> c1.equals(c2);
 Customer c1 = new Customer(1,"Raj");
 Customer c2 = new Customer(1,"Ram");
 boolean isEqual = equalChecker.test(c1,c2);

Leave a Reply