Java 8 Streams

Java 8 Streams are designed in such a way that most of its stream operations returns Streams only. This help us creating chain of various stream operations. This is called as pipelining.

A stream pipeline consists of a source (such as a Collection, an array, a generator function, or an I/O channel); followed by zero or more intermediate operations such as Stream.filter or Stream.map; and a terminal operation such as Stream.forEach or Stream.reduce.

Streams vs. Collections:

A Collection is an in-memory data structure, which holds all the values that the data structure currently has—every element in the Collection has to be computed before it can be added to the Collection. A Stream is a conceptually fixed data structure, in which elements are computed on demand. This gives rise to significant programming benefits.

In java, java.util.Stream represents a stream on which one or more operations can be performed. Stream operations are either intermediate or terminal. While terminal operations return a result of a certain type, intermediate operations return the stream itself so you can chain multiple method calls in a row. Streams are created on a source, e.g. a java.util.Collection like lists or sets (maps are not supported). Stream operations can either be executed sequential or parallel.

If we list down the various characteristics of Stream, they will be as follows:

  • Not a data structure
  • Designed for lambdas
  • Do not support indexed access
  • Can easily be outputted as arrays or lists
  • Lazy access supported
  • Parallelizable

Build streams functions:

1) Using Stream.of(val1, val2, val3….)

         Stream stream = Stream.of(1,2,3,4,5);
         stream.forEach(p -> System.out.println(p));

2) Using Stream.of(arrayOfElements)

         Stream stream = Stream.of( new Integer[]{1,2,3,4,5} );
         stream.forEach(p -> System.out.println(p));

3) Using someList.stream()

         List list = new ArrayList();
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
         Stream stream = list.stream();
         stream.forEach(p -> System.out.println(p));

4) Using Stream.generate() or Stream.iterate() functions

public class StreamBuilders {
     public static void main(String[] args){
         Stream stream = Stream.generate(() -> { return new Date();});
         stream.forEach(p -> System.out.println(p));
5) Using String chars or String tokens

        IntStream stream = "12345_abcdefg".chars();
        stream.forEach(p -> System.out.println(p));
         
        //OR
         
        Stream stream = Stream.of("A$B$C".split("\\$"));
        stream.forEach(p -> System.out.println(p));

Converting streams to collections:


1) Convert Stream to List using stream.collect(Collectors.toList())

        List list = new ArrayList();
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
         Stream stream = list.stream();
         List evenNumList = stream.filter(i -> i%2 == 0).collect(Collectors.toList());
         System.out.print(evenNumList);
2) Convert Stream to array using stream.toArray(EntryType[]::new)

        List list = new ArrayList();
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
         Stream stream = list.stream();
         Integer[] evenNumbersArr = stream.filter(i -> i%2 == 0).toArray(Integer[]::new);
         System.out.print(evenNumbersArr);
  

Stream operations and pipelines

Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines
public class SampleExample {. 
  public static void main(String arg[]){
  List studentName=new ArrayList();
  studentName.add("Sonali");
  studentName.add("Monali");
  studentName.add("Saanvi");
  studentName.add("Kiansh");
  studentName.add("Surya");
 }
}

A) filter()

memberNames.stream().filter((s) -> s.startsWith("S"))
                    .forEach(System.out::println); //print  Sonali Saaanvi
B) map()
memberNames.stream().filter((s) -> s.startsWith("A"))
                     .map(String::toUpperCase)
                     .forEach(System.out::println); //print SONALI SAANVI

Terminal operations :

Terminal operations return a result of a certain type instead of again a Stream.

A) forEach()

This method helps in iterating over all elements of a stream and perform some operation on each of them. The operation is passed as lambda expression parameter.

memberNames.forEach(System.out::println);

No comments: