Posts Tagged ‘Java8’

How can we process really large collections efficiently? Normally we used loops to iterate over a collection.

Lets say we need to iterate over a list of Person object

List<Person> personList = new ArrayList<>();
personList.add(new Person("Sam", 10));
personList.add(new Person("Smith", 9));
personList.add(new Person("Zayn", 2));
personList.add(new Person("Nathan", 1));

Using foreach loop

personList.forEach(person -> {
    System.out.println(" Person Name :: " + person.getName());
});

In Java 8, we have something new called “Stream”. A stream represents a sequence of elements and supports different kind of operations to perform computations upon those elements.

System.out.println("Traversing List using streams.");
personList.stream().forEach(person -> {
    System.out.println(person.getName());
});

It may seem Java 8’s stream api is a bit verbose than the for-each loop for collections. And we wonder what benefit can come from it.

The difference between for-each loop and using stream api (collection.stream()) in Java 8 is that, we can easily implement parallelism when using the stream api with collection.parallelStream(). Whereas, in for-each loop you will have to handle threads on your own.

/**One of the goals of the stream API in Java8 is to let you break up processing on a system that has multiple CPUs.
 * This multi CPU processing is handled automatically by the Java runtime.
 * All you need to do is turn your sequential stream into a parallel stream.
 */
System.out.println("Traversing List using Parellel streams");
personList.parallelStream().forEach(person -> {
    System.out.println(person.getName());
});

 

Stream operations are either intermediate or terminal. Intermediate operations return a stream so we can chain multiple intermediate operations without using semicolons. Terminal operations are either void or return a non-stream result. In the above example filter, map and sorted are intermediate operations whereas forEach is a terminal operation. For a full list of all available stream operations see the Stream Javadoc. Such a chain of stream operations as seen in the example below is also known as operation pipeline. 

Predicate<Person> agePredicate = person -> person.getAge() > 5;
System.out.println("Traversing List using Parellel streams and filters");
personList.parallelStream()
        .filter(nameAndAgePredicate)
        .sorted()
        .forEach(person -> {
    System.out.println(person.getName());
});

Lets see the different ways of creating stream

Arrays.asList("sam", "smith", "zayn")
        .stream()
        .findFirst()
        .ifPresent(System.out::println);

Stream.of("sam", "smith", "zayn")
        .findFirst()
        .ifPresent(s -> System.out.println(s));
Arrays.stream(new int[] {1, 2, 3})
        .average()
        .ifPresent(System.out::println);
Advertisements

In addition to the new lambda syntax, Java SE8 adds a number of new functional interfaces. One of the most useful is called the Predicate Interface which is an interface that has a single boolean method named Test, that you can use to wrap up your conditional processing, and make conditional code a lot cleaner.

Go through the following example and you will get an understanding of Predicate Interface

package com.suhas;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;


public class PredicateInterfaceTest {

    public static void main(String[] args) {

        List<Person> personList = new ArrayList<>();
        personList.add(new Person("Sam", 10));
        personList.add(new Person("Smith", 9));
        personList.add(new Person("Zayn", 6));
        personList.add(new Person("Nathan", 1));

        Predicate<Person> agePredicate = person -> person.getAge() > 5;

        Predicate<Person> namePredicate = person -> person.getName().equals("Zayn");

        Predicate<Person> nameAndAgePredicate = namePredicate.and(person -> person.getAge() < 5);

        personList.forEach(person -> {
            if (agePredicate.test(person))
                System.out.println("Matching Record Found for Age Predicate :: " + person.getName());
            if (namePredicate.test(person))
                System.out.println("Matching Record Found for Name Predicate :: " +  person.getName());
            if (nameAndAgePredicate.test(person))
                System.out.println("Matching Record Found for Name and Age Predicate :: " +  person.getName());

        });

    }
}