openplanning

Hướng dẫn và ví dụ Java Predicate

Xem thêm các chuyên mục:

Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook

1- Predicate

Trong Java 8, Predicate là một functional interface, đại diện cho một toán tử chấp nhận một tham số đầu vào và trả về một giá trị boolean.
Predicate

@FunctionalInterface
public interface Predicate<T> {
  boolean test(T t);
}
Ví dụ: Tạo một Predicate để kiểm tra một số có phải là số lẻ hay không.
PredicateEx1.java

package org.o7planning.ex;

import java.util.function.Predicate;

public class PredicateEx1 {

    public static void main(String[] args) {
        
        Predicate<Integer> tester = value -> value % 2 == 1;
        
        int value = 11;
        
        System.out.println(value + " Is an Odd Number? " + tester.test(value));
    }
}
Output:

11 Is an Odd Number? true
Predicate cũng được sử dụng để kiểm tra các phần tử trong một danh sách có phù hợp với một điều kiện nào đó hay không.
Ví dụ: Một danh sách các số Integer, chúng ta sẽ lọc ra một danh sách mới chỉ bao gồm các số lẻ.
PredicateEx2.java

package org.o7planning.ex;

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

public class PredicateEx2 {

    public static void main(String[] args) {

        Predicate<Integer> tester = value -> value % 2 == 1;

        List<Integer> list = Arrays.asList(10, 11, 13, 14, 15, 16, 17);

        // @see: stream.filter(Predicate)
        List<Integer> newList = list.stream() //
                .filter(tester).collect(Collectors.toList());
 
        // @see: list.forEach(Consumer)
        newList.forEach(System.out::println);
    }
}
Output:

11
13
15
17
Ví dụ: Từ một danh sách các tên người, chỉ in ra những người có tên bắt đầu bởi chữ "S":
PredicateEx3.java

package org.o7planning.ex;

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

public class PredicateEx3 {

    public static void main(String[] args) {

        Predicate<String> tester = name -> name.startsWith("S");

        List<String> names = Arrays.asList("John", "Smith", "Samueal", "Catley", "Sie");

        // @see: stream.filter(Predicate)
        // @see: stream.forEach(Consumer)
        names.stream().filter(tester).forEach(System.out::println);
    }
}
Output:

Smith
Samueal
Sie

2- Predicate + Method reference

Tiếp theo chúng ta đến với các ví dụ tạo một Predicate từ tham chiếu của một phương thức, hai lớp EmployeeEmployeeUtils sẽ tham gia vào các ví dụ này.
Employee.java

package org.o7planning.ex;

public class Employee {

    private String name;
    private float salary;
    private String gender; // "M", "F"

    public Employee(String name, float salary, String gender) {
        this.name = name;
        this.salary = salary;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public float getSalary() {
        return salary;
    }

    public String getGender() {
        return gender;
    }

    public boolean isFemale() {
        return "F".equals(this.getGender());
    }
}
EmployeeUtils.java

package org.o7planning.ex;

public class EmployeeUtils {
    
    public static boolean isHighSalary(Employee e) {
        return e.getSalary() > 5000;
    }
}
M.ref Example 1:
Nếu một phương thức tĩnh có một tham số kiểu <T> và trả về kiểu boolean, thì tham chiếu của nó có thể coi là một Predicate<T>:
Ví dụ: Phương thức tĩnh EmployeeUtils.isHighSalary(Employee) là một Predicate<Employee>:

Predicate<Employee> p = EmployeeUtils::isHighSalary;

// Same as:

Predicate<Employee> p = employee -> EmployeeUtils.isHighSalary(employee);
Predicate_mr_ex1.java

package org.o7planning.ex;

import java.util.function.Predicate;

public class Predicate_mr_ex1 {

    public static void main(String[] args) {
        
        Employee sophia = new Employee("Sophia B.", 7000, "F");
        
        // Create a Predicate from a method reference.
        Predicate<Employee> tester = EmployeeUtils::isHighSalary;
        
        System.out.println("High Salary? " + tester.test(sophia));
    }
}
Output:

High Salary? true
M.ref Example 2:
Employee.isFemale() là một phương thức không tĩnh (non-static), không tham số, và trả về kiểu boolean, tham chiếu của nó được coi như một Predicate<Employee>:

Predicate<Employee> p = Employee::isFemale;

// Same as:

Predicate<Employee> p = employee -> employee.isFemale();
Predicate_mr_ex2.java

package org.o7planning.ex;

import java.util.function.Predicate;

public class Predicate_mr_ex2 {

    public static void main(String[] args) {
        
        Employee sophia = new Employee("Sophia B.", 7000, "F");
        
        // Create a Predicate from a method reference.
        Predicate<Employee> tester = Employee::isFemale;
        
        System.out.println("High Salary? " + tester.test(sophia));
    }
}
Output:

High Salary? true

3- negate()

Phương thức negate() trả về một đối tượng Predicate mới mà kết quả đánh giá của nó là phủ định của Predicate hiện tại.

default Predicate<T> negate() {
    return (t) -> !test(t);
}
Ví dụ: Một danh sách các số Integer, chúng ta sẽ lọc ra một danh sách mới chỉ bao gồm các số chẵn.
PredicateEx7.java

package org.o7planning.ex;

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

public class PredicateEx7 {

    public static void main(String[] args) {

        
        // Checks if a number is odd.
        Predicate<Integer> tester = value -> value % 2 == 1;

        List<Integer> list = Arrays.asList(10, 11, 13, 14, 15, 16, 17);

        // @see: stream.filter(Predicate)
        List<Integer> newList = list.stream() //
                .filter(tester.negate()).collect(Collectors.toList());
 
        // @see: list.forEach(Consumer)
        newList.forEach(System.out::println);
    }
}
Output:

10
14
16

4- and(Predicate other)

Phương thức and(other) tạo ra một đối tượng Predicate mới từ việc kết hợp đối tượng Predicate hiện tại và other, nó được đánh giá là true nếu cả hai, Predicate hiện tại và other đều được đánh giá là true.

default Predicate<T> and(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
}
Ví dụ: Một danh sách các số Integer, chúng ta sẽ lọc ra một danh sách mới chỉ bao gồm các số lẻ và lớn hơn 20.
PredicateEx8.java

package org.o7planning.ex;

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

public class PredicateEx8 {

    public static void main(String[] args) {

        // Test if a number is odd.
        Predicate<Integer> tester1 = value -> value % 2 == 1;
        // Test if anumber > 20
        Predicate<Integer> tester2 = value -> value > 20;

        List<Integer> list = Arrays.asList(10, 11, 13, 14, 15, 16, 17, 25, 27, 26, 28);

        // A List of odd and greater than 20.
        // @see: stream.filter(Predicate)
        List<Integer> newList = list.stream() //
                .filter(tester1.and(tester2)).collect(Collectors.toList());
 
        // @see: list.forEach(Consumer)
        newList.forEach(System.out::println);
    }
}
Output:

25
27

5- or(Predicate other)

Phương thức or(other) trả về một đối tượng Predicate mới từ việc kết hợp đối tượng Predicate hiện tại và other, nó được đánh giá là true nếu một trong hai, Predicate hiện tại hoặc other được đánh giá là true.

default Predicate<T> or(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
}
Ví dụ: Cho một danh sách tên người, in ra những tên bắt đầu bởi chữ "A" hoặc kết thúc với chữ "p".
PredicateEx9.java

package org.o7planning.ex;

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

public class PredicateEx9 {

    public static void main(String[] args) {

        List<String> names = Arrays.asList("Peter", "Martin", "Alex", "Philip", "Piyush", "Mike");

        Predicate<String> tester1 = name -> name.startsWith("A");
        Predicate<String> tester2 = name -> name.endsWith("p");

        // find a name starts with "A" or ends with "p"
        names.stream().filter(tester1.or(tester2)).forEach(System.out::println);
    }
}
Output:

Alex
Philip

6- isEqual(Object targetRef)

Phương thức tĩnh Predicate.isEqual(targetRef) trả về một Predicate để kiểm tra 2 đối tượng bằng nhau hay không bằng cách sử dụng phương thức Objects.equals(Object,Object).

static <T> Predicate<T> isEqual(Object targetRef) {
    return (null == targetRef)
            ? Objects::isNull
            : object -> targetRef.equals(object);
}
PredicateEx10.java

package org.o7planning.ex;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

public class PredicateEx10 {

    public static void main(String[] args) {

        Predicate<String> test1 = Predicate.isEqual("Mike");
        
        // test1 same as test2:
        Predicate<String> test2 = myIsEqual("Mike");
        
        List<String> names = Arrays.asList(
                "Peter",
                "Martin",
                "Alex",
                "Philip",
                "Piyush",
                "Mike"
               );
             
               
       // Find a name that is equals "Mike"
       names.stream()
            .filter(test1)
            .forEach(System.out::println);
    }

    public static <T> Predicate<T> myIsEqual(Object targetRef) {
        Predicate<T> tester = obj -> Objects.equals(obj, targetRef);
        return tester;
    }
}
Output:

Mike

Xem thêm các chuyên mục: