Streams In Java8


Streams Introduction:

In Java8, new feature 'Stream' was introduced into the java.util.stream package.

Why do we need Streams?
In Previous versions of Java, Developer has to loop through the Collections and  needs to have  repeated checks for nulls, which was error prone and more tedious process. Oracle Team came up with this Stream Approach.

What is Stream?
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.

Simple words "Stream represents a sequence of objects from a source, which is used for Computational operations"

•  Stream is not a Data Structure that stores elements.
•  An operation on a stream produces a result, but it does not modify its source.
•  Stream operations are divided into two
    • intermediate (Stream-producing) operations and 
    • terminal (value- or side-effect-producing) operations.
    • Intermediate operations are always lazy.
• The elements of a stream are pipelined only once. New stream must be created for looping again.

Structure of Stream:
It consists of a 
  • Source, 
  • zero or more intermediate operations and a 
  • Terminal operation.





Source-> (0 or more) Intermediate Operations-->Terminal Operation

Example:
Stream<Transactions> s1=transaction.stream()    // source
Stream<Transactions> s2=s1.filter(t->t.getBuyer().getState().equals(“WGL”)); // intermediate
IntStream s3=s2.mapToInt(Transactions::getPrice); // intermediate

int sum=s3.sum(); // terminal

Different ways of creating Stream Source?
  1. Collection.stream() or Collection.parallelStream()
  2. Arrays.stream()
  3. From static factory methods like
    • Stream.of()
    • IntStream.range(int int)
    • Stream.iterator(Object,UnaryOperator)
  4. BufferedReader.lines()
  5. Random.ints()
  6. BitSet.stream()

Different ways of creating Stream Intermediate Operation?
Methods that return new streams are called as Intermediate operations.
Intermediate operations are divided into Stateless and Stateful operations

Stateless operations will not return any state from a previously seen element when processing a new element.
  1. Stream.filter()
  2. Stream.map()
  3. distinct()
  4. sorted()
  5. filterMap()
  6. limit()

Stateful operations will incorporate state from previously seen elements when processing a new elements.
  1. Stream.distinct()
  2. Stream.sorted()

Different ways of creating Stream Terminal Operation?
  1. Iterating: Stream.forEach()
  2. Stream.reduce(),collect(),toArray()
  3. Aggregation : IntStream.sum(), min(),max(),count(), anyMatch(),allMatch()
  4. Searching : findFirst(), findAny() 

Reduce:
It combines all the elements in a stream to produce a single value.
It takes two parameters 
  • Seed 
  • Accumulator
If Stream is empty then seed is the result. Accumulator is a function.

Seed and an element are passed to the accumulator, which returns partial result and then partial result and next element are passed to the accumulator function this repeats till all elements are passed to the accumulator function and last value is returned is the result.

Infinite streams:

There are two static methods—

  1. Stream.iterate and 
  2. Stream .generate—

that let you create a stream from a function


Example:

Stream<Integer> numbers = Stream.iterate(0, n -> n + 10);







Debug Streams:


To Debug stream there is a plugin “Java Stream Debugger”, which is useful in debugging the streams


https://plugins.jetbrains.com/plugin/9696-java-stream-debugger/versions


After plugin in installed 


  1. Keep Debug point 
  2. Run in debug mode
  3. click on last option Stream trace
  4. We see tabs of the stream we applied and can see the output of each operation



Comments

Popular posts from this blog

Apache Spark