Stream


Stream

A stream in Java is a sequence of data. It helps us in performing various operations with the data. This data can be obtained from several sources such as Collections, Arrays.
Stream API is basically bulk operations and process the objects of collection. A stream does not store data and, in that sense, is not a data structure. It also never modifies the underlying data source.

Stream is conceptually a pipeline, in which elements are computed on demand. Stream reduce the code length.

stream operation
Stream Pipeline

A stream pipeline is nothing but combined intermediate and terminal operations.
Many stream operations return a stream themselves. This allows operations to be chained to form a larger pipeline.
Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines.

Intermediate

These methods usually accept functional interfaces as parameters and always return a new stream.
Functional interface parameter!! that means, We can use lambda expressions here.
Using lambda expressions which can participate an 'internal iteration'.
Ex. Filtering, Sorting, Type Conversion, Mapping etc.

Terminal Operations

A terminal stream operation is an operation that starts the internal iteration of the elements, calls all the listeners, and returns a result.
Ex. Count, Sum, Collecting a collection etc.


Creating Stream

There are several ways to create a Stream in Java.
Stream from a Collection using stream() List<String> list = ArrayList<String>();
list.add("AAA");
list.add("BBB");
list.add("CCC");

Stream<String> streamofStrings = list.stream();
// creating a sequential stream (used most of the time)
Stream from an Array using Arrays.stream() String[] arr= new String[] { "a", "b", "c" }; Stream<String> streamOfStrings = Arrays.stream(arr); Creating an Empty Stream using Stream.empty() Stream<String> emptyStream = Stream.empty();

Intermediate

Intermediate operations return the stream itself so you can chain multiple methods calls in a row. These methods usually accept functional interfaces as parameters and always return a new stream.

Stream.filter() Method

The filter() method accepts a Predicate to filter all elements of the stream. This operation is intermediate which enables us to call another stream operation (e.g. forEach()) on the result. List<String> memberNames = new ArrayList<>();
memberNames.add("Amitabh");
memberNames.add("Shekhar");
memberNames.add("Aman");

memberNames.stream().filter((s) -> s.startsWith("A"))
.forEach(System.out::println);

Output:
Amitabh
Aman

Stream.map() Method

The map() intermediate operation converts each element in the stream into another object via the given function. List<String> memberNames = new ArrayList<>();
memberNames.add("Amitabh");
memberNames.add("Shekhar");
memberNames.add("Aman");

memberNames.stream().filter((s) -> s.startsWith("A"))
.map(String::toUpperCase)
.forEach(System.out::println);

Output:
AMITABH
AMAN

Stream.sorted() Method

The sorted() method is an intermediate operation that returns a sorted view of the stream. The elements in the stream are sorted in natural order unless we pass a custom Comparator. List<String> memberNames = new ArrayList<>();
memberNames.add("Amitabh");
memberNames.add("Shekhar");
memberNames.add("Aman");

memberNames.stream().sorted()
.map(String::toUpperCase)
.forEach(System.out::println);

Output:
Aman
Amitabh
Shekhar

Terminal operations

Terminal operations return a result of a certain type after processing all the stream elements. Once the terminal operation is invoked on a Stream, the iteration of the Stream and any of the chained streams will get started. Once the iteration is done, the result of the terminal operation is returned.

Collection

List<String> memberNames = new ArrayList<>();
memberNames.add("Amitabh");
memberNames.add("Shekhar");
memberNames.add("Aman");

Stream.forEach() Method

The forEach() method helps in iterating over all elements of a stream and perform some operation on each of them. The operation to be performed is passed as the lambda expression. memberNames.forEach(System.out::println);

Output:
Shekhar
Amitabh
Aman

Stream.collect() method

The collect() method is used to receive elements from a steam and store them in a collection. List<String> memNamesInUppercase = memberNames.stream().sorted()
.map(String::toUpperCase)
.collect(Collectors.toList());

System.out.print(memNamesInUppercase);

[AMAN, AMITABH, SHEKHAR]

Stream.count() method

The count() is a terminal operation returning the number of elements in the stream as a long value. long totalMatched = memberNames.stream()
.filter((s) -> s.startsWith("A"))
.count();

System.out.println(totalMatched);

Output: 2