What is Java Stream ? Explain with Examples

What is a Stream in Java 8?

Another Java 8 important feature, it can be defined as a pipeline through which a collection of objects and primitive data can be streamed through and a set of operations are performed over each object.

streams

In other words, It is used to process a collection of objects. It streams over a sequence of objects from a source ( collection of objects or primitive types ), perform intermediate operations on each and every element of that source and provide the final outcome.
A stream can be accompanied by zero or more intermediate operations.

Points to remember:

– It converts the normal list to a stream
– It is used to process data using filter, map and other, the final output can be collected to form a list

– It doesn’t manipulate original data, instead creates a new stream
– It provides various stream operation such as map, filter and more
– An element in a stream is always traversed exactly once.
– It does the stream lazily as it doesn’t traverse until the terminal operation doesn’t get executed

-It forms a pipeline where intermediate operations and terminal operations are chained together

 

There are two ways in Collection interface to produce a Stream:

stream() -> It returns a sequential stream
parallelStream() ->  Returns a parallel stream. It utilizes the multiple cores of the computer by creating multiple threads to form sub-streams and assigns them given tasks which execute in parallel.

A stream can be split into two operations. An intermediate operation where all the manipulation is done and a terminal which produces the end result.

 

Stream Source or Create a Stream

A source might represent an array, collection and other. Another way is, to create a stream and do the further opertion on that particular stream.

Create Streams

  • Stream.of

A static method that returns a squence of ordered stream.

Stream.of(val1,val2 .. ......)

Code Example :

public class CreateStreams {

    public static void main(String[] args) {
// Creating Stream of Characters
        Stream<Character> characterStream = Stream.of('P', 'R', 'O', 'G', 'R', 'A', 'M', 'M', 'E', 'R', 'B', 'A', 'Y');
// Now Printing it as a word
        characterStream.forEach(singleCharacter -> System.out.print(singleCharacter));
    }
}

Output:

PROGRAMMERBAY

One can also create Stream of array with Stream.of() method.

For example:

public class CreateStreams {

    public static void main(String[] args) {
        String[] stringArr = new String[]{"This", "is", "Example", "of", "Stream"};
        // Creating Stream of Array
        Stream<String> arrayStream = Stream.of(stringArr);
        arrayStream.forEach(singleString -> System.out.print(singleString + " "));
    }
}

Output:

This is Example of Stream
  • List.stream()

In this, a list acts like stream and all the operations are done, just as normal stream.

Code example :

public class CreateStreams {

    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("A");
        stringList.add("list");
        stringList.add("example");
        stringList.add("with");
        stringList.add("Stream");

        stringList.forEach(singleString -> System.out.print(singleString + " "));
    }
}

Output:

A list example with Stream

 

Intermediate Operations

An intermediate operation is an operation that always returns a new stream.

  • Filter()

– It allows us to put conditional checks and filter out specific element or data from the source data in form of a new stream.
– It uses predicate as an argument which always returns a boolean type.

Syntax:

filter(Predicate<? super T> predicate)
  • Map()

– It allows us to manipulate the data source or process the data and get the result from it.

– It maps each element to its corresponding result and provides a new stream.

– It accepts Function as an argument which processes a given input to provide the result.

Syntax:

map(Function<? super T,? extends R> mapper)
  • Sorted

-It sorts a list of elements as per natural order.

-However, one can achieve custom behaviour using Comparator.

Code Example :

public class CreateStreams {

    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(5);
        integerList.add(2);
        integerList.add(12);
        integerList.add(1);
        integerList.add(45);
        integerList.add(9);
        integerList.stream().sorted().forEach(System.out::println);
    }
}

Output:

1
2
5
9
12
45

Terminal Operations

A terminal operation is an operation that returns non-stream values such as Optional, object, collection and more.

  • Reduce()

A reduce method performs a certain operation on each element of a given list and produces a single output value. In simple words, it reduces a list to a single output.

-It takes two arguments, first is identity and the second one is Accumulator.

Identity: It resembles the initial value of the reduction operation and acts as a default output if no data exist in the given list.

Accumulator: It is itself a function that takes two parameters, the first one is partial output and the second argument represents the next element of the list.

Code example :

public class CreateStreams {

    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(5);
        integerList.add(5);
        integerList.add(15);
        Integer sum = integerList.stream().reduce(0,(initialVal, nextElm) -> initialVal + nextElm );
        System.out.println("Sum  : "+sum);
    }
}

Output :

Sum  : 25
  • Collect 

-It is used to translate a stream into a list.

-It simply consolidates all the processed result and returns a list

Syntax:

collect(Collector<? super T,A,R> collector)

Collecting stream data as an array :

toArray() is used to get an array as output after performing intermediate operations.

Code example: 

public class CreateStreams {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(5);
        integerList.add(10);
        integerList.add(12);
        integerList.add(15);
        integerList.add(21);
        integerList.add(24);
        Integer[] intArr = integerList.stream().filter(singleElement -> (singleElement % 5 == 0)).toArray(Integer[]::new);
        for (Integer element :
                intArr) {
            System.out.println("Multiples of 5 : " + element);
        }
    }
}

Output:

Multiples of 5 : 5
Multiples of 5 : 10
Multiples of 5 : 15

Collecting stream data as a list :

collect(Collectors.toList()) is used to get a list as output after performing intermediate operations.

Code example: 

public class CreateStreams {

    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(5);
        integerList.add(10);
        integerList.add(12);
        integerList.add(15);
        integerList.add(21);
        integerList.add(24);
        List<Integer> intList = integerList.stream().filter(singleElement -> (singleElement % 5 == 0)).collect(Collectors.toList());
        for (Integer element :
                intList) {
            System.out.println("Multiples of 5 : " + element);
        }
    }
}

Collecting stream data as a Map:

collect(Collectors.toMap() is used to get a Map as output after performing intermediate operations.

Code example: 

public class CreateStreams {

    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(5);
        integerList.add(10);
        integerList.add(12);
        integerList.add(15);
        integerList.add(21);
        integerList.add(24);
        Map<Integer,Integer> intMap = integerList.stream().filter(singleElement -> (singleElement % 5 == 0)).collect(Collectors.toMap(key -> key / 5 , value -> value));
        System.out.println("Map " + intMap);
    }
}

Output:

Map {1=5, 2=10, 3=15}
  • forEach

-Loop through each element of the given stream. It is a new feature provided in Java 8.

Syntax

forEach(Consumer<? super T> action)

 

 

Filter and forEach program example:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class StreamExample {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList(Arrays.asList(5,10,50,15,30,40));

        list.stream().filter(singleEelement -> (singleEelement > 30)).forEach(element -> System.out.println("All value greater than 30 :- "+element));
    }
}

Output:

All value greater than 30 :-50
All value greater than 30 :-40

Explanation:

Above code,  filter method is creating a stream in which only values that are greater than 30 is present, then after, simply printing it over the screen using forEach() method.

 

Map and Collect program example

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList(Arrays.asList(5,10,50,15,30,40));

      List newList =  list.stream().map(singleEelement -> singleEelement+5).collect(Collectors.toList());

    newList.forEach(element -> System.out.println(element));
    }
}

Output:

10
15
55
20
35
45

 

Explanation:

Above code,  map method is creating a stream in which each element is incremented by 5 are present, then after, simply converting it to list.

Leave a Reply