betacode

Руководство Java Predicate

  1. Predicate
  2. Predicate + Method reference
  3. negate()
  4. and(Predicate other)
  5. or(Predicate other)
  6. isEqual(Object targetRef)

1. Predicate

В Java 8, Predicate - это functional interface, представляющий оператор, который принимает входной параметр и возвращает значение boolean.
Predicate
@FunctionalInterface
public interface Predicate<T> {
  boolean test(T t);
}
Например: Создайте Predicate, чтобы проверить, является ли число нечетным или нет.
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 также используется для проверки соответствия элементов списка определенному условию.
Например: Из списка целых чисел Integer, мы отфильтруем новый список, состоящий только из нечетных чисел.
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
Например: Из списка имен людей выведите только те, чьи имена начинаются с буквы "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

Далее мы переходим к примерам создания Predicate из ссылки метода. Классы Employee и EmployeeUtils участвуют в этих примерах.
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:
Если статический метод принимает параметр типа <T> и возвращает boolean, то его ссылку можно считать Predicate<T>:
Например: Статический метод EmployeeUtils.isHighSalary(Employee) - это 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() является нестатическим методом (non-static), не имеет параметра и возвращает boolean, поэтому его ссылка считается 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()

Метод negate() возвращает новый объект Predicate, результат оценки которого является отрицательной для текущего Predicate.
default Predicate<T> negate() {
    return (t) -> !test(t);
}
Например: Из списка целых чисел Integer, мы отфильтруем новый список, содержащий только четные числа.
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)

Метод and(other) создает новый объект Predicate, объединяя текущий объект Predicate и other. Он оценивается как true, если и текущий Predicate и other оцениваются как true.
default Predicate<T> and(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
}
Например: Из списка целых чисел Integer, мы отфильтруем новый список, состоящий только из нечетных чисел и больше 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)

Метод or(other) возвращает новый объект Predicate путем объединения текущего объекта Predicate и other. Он оценивается как true, если текущий Predicate или other оценивается как true.
default Predicate<T> or(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
}
Например: Дан список имен людей, распечатайте имена, начинающиеся с буквы "А" или заканчивающиеся буквой "р".
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)

Статический метод Predicate.isEqual(targetRef) возвращает Predicate для проверки того, равны ли два объекта или нет, используя метод Object.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

Java Basic

Show More