Google

Aug 1, 2014

Java 8 using the Predicate functional interface

The java.util.function package in Java 8 has a number of functional interfaces. Let's look at the Predicate<T> interface that is used for filtering objects from a collection. If you are using a Java version pre Java 8 refer Creating sub lists from a list using predicates to filter.

Here is the Java 8 example:

Step 1: Create a Driver domain class using the builder design pattern. Refer How to create elegant immutable objects in Java for the Driver code.


public class Driver {
 enum SEX {
  MALE, FEMALE
 }

 private String name;
 private int age;
 private SEX sex;

    //builder, and getters,
 
}

If not sure how to apply the builder design pattern to the Driver class.

Step 2: Define a static method to have methods that return Predicates via static methods.

package com.java8.examples;

import java.util.function.Predicate;

public class DriverPredicate {

 public static Predicate<Driver> isEligibleForDriving() {
  return p -> p.getAge() > 18;
 }

 public static Predicate<Driver> isEligibleMaleDriver() {
  return p -> p.getAge() > 18 && p.getSex() == Driver.SEX.MALE;
 }
 
}




Step 3: Create sub lists using the predicates. It is much easier to create sub lists in Java 8.

package com.java8.examples;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DriverTest {

 public static void main(String[] args) {
  List<Driver> drivers = Arrays.asList(
    new Driver.Builder().name("John").age(34).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("James").age(24).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("Samantha").age(16).sex(Driver.SEX.FEMALE).build()
  );

  
  //using the predicates
  List<Driver> eligibleDriverList = drivers.stream().filter(DriverPredicate.isEligibleForDriving())
    .collect(Collectors.toList());

  List<Driver> eligibleMaleDriverList = drivers.stream().filter(DriverPredicate.isEligibleMaleDriver())
    .collect(Collectors.toList());
  
  System.out.println("eligibleDriverList-->" + eligibleDriverList);
  System.out.println("eligibleMaleDriverList-->" + eligibleMaleDriverList);
  
 }

}


Output:

eligibleDriverList-->[Driver [name=John, age=34, sex=MALE], Driver [name=James, age=24, sex=MALE]]
eligibleMaleDriverList-->[Driver [name=John, age=34, sex=MALE], Driver [name=James, age=24, sex=MALE]]


Optional: You could have written the above trivial code without the DriverPredicate class as shown below. But, in industrial strength applications, you will end up violation the DRY (Don't Repeat Yourself) principle by repeating the filter logic in lambda expressions in multiple places. If the rule changes, you need to modify it in multiple locations.


package com.java8.examples;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DriverTest {

 public static void main(String[] args) {
  List<Driver> drivers = Arrays.asList(
    new Driver.Builder().name("John").age(34).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("James").age(24).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("Samantha").age(16).sex(Driver.SEX.FEMALE).build()
  );

  
  //using the predicates
  List<Driver> eligibleDriverList = drivers.stream().filter(p -> p.getAge() > 18)
    .collect(Collectors.toList());

  List<Driver> eligibleMaleDriverList = drivers.stream().filter(p -> p.getAge() > 18 && p.getSex() == Driver.SEX.MALE)
    .collect(Collectors.toList());
  
  System.out.println("eligibleDriverList-->" + eligibleDriverList);
  System.out.println("eligibleMaleDriverList-->" + eligibleMaleDriverList);
  
 }

}

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home