Ernest Duodu Ernest is a Java developer. Outside programming, he also enjoys a wide variety of hobbies which includes sky-diving, photography, exercising and listening to music.

Are you a Java Developer working with PDF files?

Find out why you should be using JPedal

Java 8 streams Explained in 5 minutes

1 min read

In my previous article I explained Java 8 Lambda Expression and how easy it is to use. In this article, we will take a quick look at Java 8 Streams .

Stream is a new feature 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));
        }
       
    }

If you found this article useful, you may also be interested in our other Java8 posts on Lambda Expression, Consumer Suppliers, Default Methods / Method References, Optional and Repeating Annotations.

We also now have large collection of articles on what is new in other versions of Java, including Java9



Our software libraries allow you to

Convert PDF to HTML in Java
Convert PDF Forms to HTML5 in Java
Convert PDF Documents to an image in Java
Work with PDF Documents in Java
Read and Write AVIF, HEIC, WEBP and other image formats
Ernest Duodu Ernest is a Java developer. Outside programming, he also enjoys a wide variety of hobbies which includes sky-diving, photography, exercising and listening to music.

7 Replies to “Java 8 streams Explained in 5 minutes”

  1. Thanks for your example

    I’m trying hard to make it work with NetBeans 8.0.1 but I get the error “incompatibe parameters types in Lambda expression” at the following statements:
    printNames(persons, p -> p.getAge() p.getName())

    1. Ken, What you need is printNames(persons, p -> p.getAge() < some number), and printNames(persons, p -> p.getName().matches(“Some String”) );. They need to be on separate lines. Hope this helps

  2. I would recommend to change the method printNames signature into
    private static void printNames(List persons, Predicate predicate)

  3. Ah i see, this site treats generics as html elements
    private static void printNames(List<Person> persons, Predicate<Person> predicate)

  4. In Eclipse Neon, those codes in format p -> getSth() need to be “casted” as ((Person) p) -> getSth().
    At my first glance, i had the same feeling with the compiler that how to understand the class type of p.
    It seems explicit casting is usually needed in java

Comments are closed.