Pages

Stream In Java 8

They are used to create pipelines of operations. It is divided into two operations, which are the terminal, and intermediate operation. Lets take a look at the example below.

private static void printNames(List persons, Predicate predicate) {
            persons.stream()
                    .filter(predicate)
                    .map(p -> ((Person) p).getName())
                    .forEach(name -> System.out.println(name));
        }
       
    }
In the code above, the filter(predicate) , map(p -> ((Person) p).getName()) and the sorted() are the intermediate operations while the forEach(name -> System.out.println(name)) is the terminal operations.
Intermediate operations are lazy.What this means is they do not actually perform any work until the terminal operation is being called.Intermediate operation such as filter produces a new stream from the main stream that matches the predicate being given to it.
Intermediate operations are also divided into two operations which are the stateful and stateless opeartion. The stateless operations such as the filter() and map()does not keep state of previous data seen when processing new data whiles the stateful operation i.e sorted() may include states from previous seen data when producing new data.
Now lets take a look at the code below and see how Java 8 Streams are used.


import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Predicate;
     
    public class Lambda {
       
        private enum Gender  { MALE, FEMALE }
       
        private static class Person {
           
            private final String name;
            private final int age;
            private final Gender gender;
           
            public Person(String name, int age, Gender gender) {
                this.name = name;
                this.age = age;
                this.gender = gender;
            }
           
            public String getName() {
                return name;
            }
           
            public int getAge() {
                return age;
            }
           
            public Gender getGender() {
                return gender;
            }
        }
       
       
        public static void main(String[] args) {
           
            List persons = new ArrayList<>();
            persons.add(new Person("Albert", 80, Gender.MALE));
            persons.add(new Person("Ben", 15, Gender.MALE));
            persons.add(new Person("Charlote", 20, Gender.FEMALE));
            persons.add(new Person("Dean", 6, Gender.MALE));
            persons.add(new Person("Elaine", 17, Gender.FEMALE));
           
            // How much code would you need to do the following without Lambdas?
            System.out.println("----------Printing Persons with age less than 18----------");
            printNames(persons, p -> ((Person) p).getAge() < 18);
            System.out.println("\n--------Printing all Males-------------");
            printNames(persons, p -> ((Person) p).getGender() == Gender.MALE);
            System.out.println("\n---------Printing Persons with Names starting With C------------");
            printNames(persons, p -> ((Person) p).getName().startsWith("C"));
           
        }
       
  private static void printNames(List persons, Predicate predicate) {
            persons.stream()
                    .filter(predicate)
                    .map(p -> ((Person) p).getName())
                    .forEach(name -> System.out.println(name));
        }
       
    }