Predicate trong Java 8

1. Giới thiệu Predicate<T>

Trong Java 8, Predicate<T> là một functional interface và do đó nó có thể được sử dụng với lambda expression hoặc method reference cho một mục đích cụ thể nào đó. Predicate<T> sẽ trả về giá trị true/false của một tham số kiểu T mà bạn đưa vào có thỏa với điều kiện của Predicate đó hay không, cụ thể là điều kiện được viết trong phương thức test().

Interface Predicate được khai báo trong package java.util.function như sau:

Trong đó:

  • boolean test(T t) : là một phương thức trừu tượng có thể được sử dụng với lambda expression hoặc method reference cho một mục đích cụ thể nào đó.
  • Phương thức test() trả về true nếu đối số đầu vào khớp với biến predicate (điều kiện kiểm tra), nếu không trả về false.

Một số phương thức mặc định (default method) trong lớp Interface Predicate:

  • and() : Nó thực hiện logic AND của predicate mà nó được gọi với một biến predicate khác. Ví dụ: predicate1.and (predicate2).
  • or() : Nó thực hiện logic OR của predicate mà nó được gọi với một biến predicate khác. Ví dụ: predicate1.or(predicate2).
  • negate() : Nó thực hiện phủ định kết quả của biến predicate được gọi. Ví dụ: predicate1.negate().

Ngoài ra interface Predicate còn có một phương thức tĩnh (static method) là isEqual(). Phương thức này được sử dụng để kiểm tra hai đối có số bằng nhau theo Objects.equals (Object, Object).

2. Một số ví dụ

2.1. Sử dụng test()

package com.maixuanviet.predicate;
 
import java.util.function.Predicate;
 
public class PredicateExample1 {
 
    public static void main(String[] args) {
 
        // Predicate String
        Predicate<String> predicateString = s -> {
            return s.equals("maixuanviet");
        };
        System.out.println(predicateString.test("maixuanviet")); // true
        System.out.println(predicateString.test("GP Coder")); // false
 
        // Predicate integer
        Predicate<Integer> predicateInt = i -> {
            return i > 0;
        };
        System.out.println(predicateInt.test(1)); // true
        System.out.println(predicateInt.test(-1)); // false
    }
}

2.2. Sử dụng and(), or(), negate(), isEqual()

package com.maixuanviet.predicate;
 
import java.util.function.Predicate;
 
public class PredicateExample2 {
 
    public static void main(String[] args) {
 
        Predicate<String> predicate = s -> {
            return s.equals("maixuanviet");
        };
 
        // AND logical operation
        Predicate<String> predicateAnd = predicate.and(s -> s.length() == 11);
        System.out.println(predicateAnd.test("maixuanviet.com")); // true
 
        // OR logical operation
        Predicate<String> predicateOr = predicate.or(s -> s.length() == 11);
        System.out.println(predicateOr.test("maixuanviet.com")); // true
 
        // NEGATE logical operation
        Predicate<String> predicateNegate = predicate.negate();
        System.out.println(predicateNegate.test("maixuanviet")); // false
    }
}

2.3. Kết hợp nhiều Predicate

package com.maixuanviet.predicate;
 
import java.util.function.Predicate;
 
public class PredicateExample3 {
 
    public static void main(String[] args) {
 
        // Creating predicate
        Predicate<Integer> greaterThanTen = (i) -> i > 10;
        Predicate<Integer> lessThanTwenty = (i) -> i < 20;
 
        // Calling Predicate Chaining
        boolean result = greaterThanTen.and(lessThanTwenty).test(15);
        System.out.println(result); // true
 
        // Calling Predicate method
        boolean result2 = greaterThanTen.and(lessThanTwenty).negate().test(15);
        System.out.println(result2); // false
    }
}
&#91;/code&#93;
<!-- /wp:shortcode -->

<!-- wp:heading {"level":3} -->
<h3>2.4. Sử dụng Predicate vơi Collection</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Ví dụ chúng ta có thông tin Employee bao gồm các thông tin id, tên, tuổi, giới tính, … như bên dưới:</p>
<!-- /wp:paragraph -->

<!-- wp:shortcode -->

package com.maixuanviet.predicate;
 
public class Employee {
 
    private Integer id;
    private Integer age;
    private String gender;
    private String firstName;
    private String lastName;
 
    public Employee(Integer id, Integer age, String gender, String fName, String lName) {
        this.id = id;
        this.age = age;
        this.gender = gender;
        this.firstName = fName;
        this.lastName = lName;
    }
 
    @Override
    public String toString() {
        return this.id.toString() + " - " + this.age.toString();
    }
 
    // Please generate Getter and Setters
}

Bây giờ chúng ta sẽ xây dựng các Predicate để thực thi như sau:

package com.maixuanviet.predicate;
 
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
 
public class EmployeePredicates {
 
    // Tất cả Employee có tuổi > 21 và có giới tính là Male
    public static Predicate<Employee> isAdultMale() {
        return p -> p.getAge() > 21 && p.getGender().equalsIgnoreCase("M");
    }
 
    // Tất cả Employee có tuổi > 18 và có giới tính là Female
    public static Predicate<Employee> isAdultFemale() {
        return p -> p.getAge() > 18 && p.getGender().equalsIgnoreCase("F");
    }
 
    // Tất cả Employee lớn hơn số tuổi được truyền vào
    public static Predicate<Employee> isAgeMoreThan(Integer age) {
        return p -> p.getAge() > age;
    }
 
    // Lấy danh sách Employee thõa mãn predicate được truyền vào
    public static List<Employee> filterEmployees( //
            List<Employee> employees, Predicate<Employee> predicate) {
        return employees.stream().filter(predicate).collect(Collectors.<Employee>toList());
    }
}

Chúng ta sẽ bắt đầu apply các Predicate này như sau:

package com.maixuanviet.predicate;
 
import static com.maixuanviet.predicate.EmployeePredicates.filterEmployees;
import static com.maixuanviet.predicate.EmployeePredicates.isAdultFemale;
import static com.maixuanviet.predicate.EmployeePredicates.isAdultMale;
import static com.maixuanviet.predicate.EmployeePredicates.isAgeMoreThan;
 
import java.util.Arrays;
import java.util.List;
 
public class EmployeePredicatesTest {
 
    public static void main(String[] args) {
 
        List<Employee> employees = Arrays.asList( //
                new Employee(1, 23, "M", "Rick", "Beethovan"), //
                new Employee(2, 13, "F", "Martina", "Hengis"), //
                new Employee(3, 43, "M", "Ricky", "Martin"), //
                new Employee(4, 26, "M", "Jon", "Lowman"), //
                new Employee(5, 19, "F", "Cristine", "Maria"), //
                new Employee(6, 15, "M", "David", "Feezor"), //
                new Employee(7, 68, "F", "Melissa", "Roy"), //
                new Employee(8, 79, "M", "Alex", "Gussin"), //
                new Employee(9, 15, "F", "Neetu", "Singh"), //
                new Employee(10, 45, "M", "Naveen", "Jain") //
        );
 
        // Lấy danh sách Employee nam 21+
        System.out.println(filterEmployees(employees, isAdultMale()));
 
        // Lấy danh sách Employee nữ 18+
        System.out.println(filterEmployees(employees, isAdultFemale()));
 
        // Lấy danh sách Employee > 35 tuổi
        System.out.println(filterEmployees(employees, isAgeMoreThan(35)));
 
        // Lấy danh sách Employee <= 35 tuổi
        System.out.println(filterEmployees(employees, isAgeMoreThan(35).negate()));
    }
}
&#91;/code&#93;
<!-- /wp:shortcode -->

<!-- wp:paragraph -->
<p>Output của chương trình trên như sau:</p>
<!-- /wp:paragraph -->

<!-- wp:shortcode -->

[1 - 23, 3 - 43, 4 - 26, 8 - 79, 10 - 45]
[5 - 19, 7 - 68]
[3 - 43, 7 - 68, 8 - 79, 10 - 45]
[1 - 23, 2 - 13, 4 - 26, 5 - 19, 6 - 15, 9 - 15]

2.5. Sử dụng Predicate với các lớp cho kiểu dữ liệu nguyên thủy (primitive type)

Java 8 cung cấp một số Interface Predicate cho các wrapper class của kiểu dữ liệu nguyên thủy như sau:

  • IntPredicate : chấp nhận một giá trị kiểu Int duy nhất.
  • LongPredicate : chấp nhận một giá trị kiểu Long duy nhất.
  • DoublePredicate : chấp nhận một giá trị kiểu Double duy nhất.

Ví dụ:

package com.maixuanviet.predicate;
 
import java.util.Arrays;
import java.util.function.DoublePredicate;
import java.util.function.IntPredicate;
import java.util.function.LongPredicate;
 
public class PredicateExample4 {
 
    public static void main(String[] args) {
 
        System.out.print("IntPredicate: ");
        int[] intNumbers = { 3, 5, 6, 2, 1 };
        IntPredicate intPredicate = i -> i > 5;
        Arrays.stream(intNumbers).filter(intPredicate).forEach(System.out::println);
 
        System.out.print("\nLongPredicate: ");
        long[] longNumbers = { 3, 5, 6, 2, 1 };
        LongPredicate longPredicate = l -> l > 5;
        Arrays.stream(longNumbers).filter(longPredicate).forEach(System.out::println);
 
        System.out.print("\nDoublePredicate: ");
        double[] dbNumbers = { 3.2, 5.0, 6.3, 2.5, 1.0 };
        DoublePredicate dbPredicate = d -> d > 5;
        Arrays.stream(dbNumbers).filter(dbPredicate).forEach(System.out::println);
    }
}

Output của chương trình trên:

IntPredicate: 6
 
LongPredicate: 6
 
DoublePredicate: 6.3

2.6. Sử dụng Predicate 2 đối số với BiPredicate

Như đã nói ở phần trên Predicate chỉ chấp nhận 1 đối số đầu vào và trả về 1 giá trị true/false, để có thể sử dụng Predicate với 2 đối số đầu vào chúng ta sử dụng Interface BiPredicate:

Về cơ bản, interface BiPredicate không khác biệt so với Predicate, ngoại trừ nó chấp nhận 2 đối số đầu vào.

package com.maixuanviet.predicate;
 
import java.util.function.BiPredicate;
 
public class BiPredicateExample {
 
    public static void main(String[] args) {
 
        BiPredicate<Integer, String> condition = (i, s) -> i > 2 && s.startsWith("J");
        System.out.println(condition.test(5, "Java")); // true
        System.out.println(condition.test(2, "Javascript")); // false
        System.out.println(condition.test(1, "C#")); // false
    }
}

Related posts:

Spring REST API with Protocol Buffers
Java Program to Print the Kind of Rotation the AVL Tree is Undergoing
Get and Post Lists of Objects with RestTemplate
Java Program to Implement the Schonhage-Strassen Algorithm for Multiplication of Two Numbers
Java Program to Implement Bucket Sort
The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5
Quick Guide to Spring Bean Scopes
Guide to Java 8’s Collectors
Java Program to Implement Hash Tables chaining with Singly Linked Lists
Java Program to Find ith Largest Number from a Given List Using Order-Statistic Algorithm
Java – Try with Resources
Convert a Map to an Array, List or Set in Java
Java Program to Implement Unrolled Linked List
@Lookup Annotation in Spring
Base64 encoding và decoding trong Java 8
Multi Dimensional ArrayList in Java
Java Program to Implement AttributeList API
Introduction to Using FreeMarker in Spring MVC
Spring RestTemplate Error Handling
Java Program to Check Cycle in a Graph using Graph traversal
Java Program to Implement Ternary Search Tree
Java Program to Check Whether a Given Point is in a Given Polygon
Tạo ứng dụng Java RESTful Client không sử dụng 3rd party libraries
Java Program to Implement Find all Forward Edges in a Graph
ETL with Spring Cloud Data Flow
Java Program to Find Number of Articulation points in a Graph
Hướng dẫn sử dụng luồng vào ra ký tự trong Java
Wiring in Spring: @Autowired, @Resource and @Inject
Java Program to Implement ConcurrentLinkedQueue API
Java Program to Implement Network Flow Problem
Java Program to Use Above Below Primitive to Test Whether Two Lines Intersect
Creating a Web Application with Spring 5