Predicate接口介绍

一、分别简单介绍下

(一)java.util.function.Predicate

Predicate是Java 8中引入的一个函数式接口,位于java.util.function包下,它在处理集合数据的筛选和条件判断等场景中非常有用。以下是对Predicate的详细介绍:

1、概念

  • Predicate接口代表了一个可以接受一个参数并返回一个布尔值的函数,用于定义一个条件测试。它可以作为一种简洁而灵活的方式来表达各种条件判断逻辑,特别是在与集合类和流(Stream)一起使用时,能够方便地对数据进行筛选和过滤。

2、 接口定义

  • Predicate接口的定义非常简洁,只有一个抽象方法test(T t),它接受一个泛型类型T的参数,并返回一个boolean值,表示该参数是否满足特定的条件。其完整定义如下:
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

3、方法和默认方法

  • test方法:这是Predicate接口中定义的唯一抽象方法,用于对给定的参数进行条件测试。例如,可以定义一个Predicate<Integer>来判断一个整数是否大于10,代码如下:
Predicate<Integer> greaterThanTen = num -> num > 10;
boolean result = greaterThanTen.test(15); // true
  • and方法:这是一个默认方法,用于将当前Predicate与另一个Predicate进行逻辑与操作,返回一个新的Predicate,只有当两个Predicatetest方法都返回true时,新的Predicatetest方法才返回true。示例如下:
Predicate<Integer> greaterThanTen = num -> num > 10;
Predicate<Integer> lessThanTwenty = num -> num < 20;
Predicate<Integer> betweenTenAndTwenty = greaterThanTen.and(lessThanTwenty);
boolean result = betweenTenAndTwenty.test(15); // true
  • or方法:同样是默认方法,用于将当前Predicate与另一个Predicate进行逻辑或操作,返回的新Predicate只要两个Predicate中的任意一个test方法返回true,其test方法就返回true。例如:
Predicate<Integer> greaterThanTen = num -> num > 10;
Predicate<Integer> lessThanFive = num -> num < 5;
Predicate<Integer> greaterThanTenOrLessThanFive = greaterThanTen.or(lessThanFive);
boolean result = greaterThanTenOrLessThanFive.test(15); // true
boolean result2 = greaterThanTenOrLessThanFive.test(3); // true
  • negate方法:该默认方法用于对当前Predicate的条件判断结果取反,返回一个新的Predicate。例如:
Predicate<Integer> greaterThanTen = num -> num > 10;
Predicate<Integer> notGreaterThanTen = greaterThanTen.negate();
boolean result = notGreaterThanTen.test(5); // true

4、使用场景

  • 集合筛选:在处理集合数据时,可以使用Predicate来筛选满足特定条件的元素。例如,从一个整数列表中筛选出所有偶数,可以这样写:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PredicateExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Predicate<Integer> isEven = num -> num % 2 == 0;
        List<Integer> evenNumbers = numbers.stream().filter(isEven).collect(Collectors.toList());
        System.out.println(evenNumbers);
    }
}
  • 数据验证:在进行数据验证时,Predicate也非常有用。比如验证一个字符串是否满足特定的格式要求,可以定义一个Predicate<String>来实现:
import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<String> isValidEmail = email -> email.matches("^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$");
        boolean result = isValidEmail.test("example@example.com");
        System.out.println(result);
    }
}
  • 动态条件构建:在一些复杂的业务场景中,可能需要根据不同的条件动态地构建查询条件。Predicate可以很好地满足这种需求,通过组合多个Predicate来创建灵活的条件表达式。例如,在一个用户查询系统中,可以根据用户输入的不同条件动态地构建查询用户的Predicate
import java.util.function.Predicate;

public class UserQueryExample {
    public static void main(String[] args) {
        Predicate<User> agePredicate = user -> user.getAge() > 18;
        Predicate<User> namePredicate = user -> user.getName().startsWith("J");

        // 根据用户输入动态组合条件
        Predicate<User> combinedPredicate = agePredicate.and(namePredicate);

        User user1 = new User("John", 25);
        User user2 = new User("Alice", 16);
        System.out.println(combinedPredicate.test(user1));
        System.out.println(combinedPredicate.test(user2));
    }
}

class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

5、总结
Predicate作为Java 8中的一个重要函数式接口,为数据的筛选、验证和条件判断等操作提供了一种简洁、灵活且类型安全的方式。通过与Lambda表达式和流(Stream)等特性相结合,可以使代码更加清晰、高效和易于维护,大大提高了Java在处理集合数据和复杂条件判断时的表达能力。

(二)com.querydsl.core.types.Predicate

com.querydsl.core.types.Predicate接口是Querydsl框架中用于构建查询条件的核心接口之一,它提供了一系列方法来创建、组合和操作查询条件,以下是对其主要方法的介绍:

  1. and(Predicate… other)
  • 功能:将当前Predicate与一个或多个其他Predicate进行逻辑与操作,返回一个新的Predicate,表示所有条件都必须满足。
  • 示例
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

public class AndExample {
    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findUsersByAgeAndName(int minAge, int maxAge, String namePart) {
        QUser qUser = QUser.user;
        BooleanExpression ageExpression = qUser.age.between(minAge, maxAge);
        BooleanExpression nameExpression = qUser.username.contains(namePart);
        Predicate predicate = ageExpression.and(nameExpression);
        JPAQuery<User> query = new JPAQuery<>(entityManager);
        return query.select(qUser).from(qUser).where(predicate).fetch();
    }
}
  1. or(Predicate… other)
  • 功能:将当前Predicate与一个或多个其他Predicate进行逻辑或操作,返回一个新的Predicate,表示只要满足其中一个条件即可。
  • 示例
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

public class OrExample {
    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findUsersByAgeOrName(int age, String namePart) {
        QUser qUser = QUser.user;
        BooleanExpression ageExpression = qUser.age.eq(age);
        BooleanExpression nameExpression = qUser.username.contains(namePart);
        Predicate predicate = ageExpression.or(nameExpression);
        JPAQuery<User> query = new JPAQuery<>(entityManager);
        return query.select(qUser).from(qUser).where(predicate).fetch();
    }
}
  1. not()
  • 功能:对当前Predicate的条件判断结果取反,返回一个新的Predicate
  • 示例
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

public class NotExample {
    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findUsersNotInAgeRange(int minAge, int maxAge) {
        QUser qUser = QUser.user;
        BooleanExpression ageExpression = qUser.age.between(minAge, maxAge);
        Predicate predicate = ageExpression.not();
        JPAQuery<User> query = new JPAQuery<>(entityManager);
        return query.select(qUser).from(qUser).where(predicate).fetch();
    }
}
  1. valueOf(boolean value)
  • 功能:创建一个始终返回指定布尔值的Predicate,主要用于在构建查询条件时提供常量条件。
  • 示例
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

public class ValueOfExample {
    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findActiveUsers(boolean isActive) {
        QUser qUser = QUser.user;
        Predicate predicate = Predicate.valueOf(isActive);
        JPAQuery<User> query = new JPAQuery<>(entityManager);
        return query.select(qUser).from(qUser).where(predicate.and(qUser.isActive.eq(isActive))).fetch();
    }
}
  1. allOf(Predicate… predicates)
  • 功能:接受多个Predicate作为参数,并返回一个新的Predicate,表示所有传入的Predicate都必须满足,等同于依次调用and方法连接所有的Predicate
  • 示例
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

public class AllOfExample {
    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findComplexUsers(int minAge, int maxAge, String namePart, boolean isActive) {
        QUser qUser = QUser.user;
        BooleanExpression ageExpression = qUser.age.between(minAge, maxAge);
        BooleanExpression nameExpression = qUser.username.contains(namePart);
        BooleanExpression activeExpression = qUser.isActive.eq(isActive);
        Predicate predicate = Predicate.allOf(ageExpression, nameExpression, activeExpression);
        JPAQuery<User> query = new JPAQuery<>(entityManager);
        return query.select(qUser).from(qUser).where(predicate).fetch();
    }
}
  1. anyOf(Predicate… predicates)
  • 功能:接受多个Predicate作为参数,并返回一个新的Predicate,表示只要满足传入的Predicate中的任意一个即可,等同于依次调用or方法连接所有的Predicate
  • 示例
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

public class AnyOfExample {
    @PersistenceContext
    private EntityManager entityManager;

    public List<User> findAnyMatchingUsers(int age1, int age2, String namePart1, String namePart2) {
        QUser qUser = QUser.user;
        BooleanExpression ageExpression1 = qUser.age.eq(age1);
        BooleanExpression ageExpression2 = qUser.age.eq(age2);
        BooleanExpression nameExpression1 = qUser.username.contains(namePart1);
        BooleanExpression nameExpression2 = qUser.username.contains(namePart2);
        Predicate predicate = Predicate.anyOf(ageExpression1, ageExpression2, nameExpression1, nameExpression2);
        JPAQuery<User> query = new JPAQuery<>(entityManager);
        return query.select(qUser).from(qUser).where(predicate).fetch();
    }
}

这些方法使得开发者能够灵活地构建各种复杂的查询条件,以满足不同的业务需求。在实际使用中,通常会结合Querydsl的查询类型(如QUser等)和其他相关的表达式来创建具体的查询条件。

(三)Google Guava

  • 简介:Google Guava是一组广泛使用的Java核心库增强工具,其中的com.google.common.base.Predicate接口与Java标准库中的java.util.function.Predicate类似,但在功能和使用方式上有一些差异和扩展。
  • 特点:Guava的Predicate接口提供了更丰富的方法和工具类来处理条件判断和过滤操作。例如,它提供了apply方法用于对对象进行条件判断,还提供了一些实用方法来组合和操作多个Predicate,如andornot等方法,这些方法与Java 8中的Predicate默认方法类似,但在Guava中可能具有更灵活的实现和不同的参数类型。
  • 示例
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.Set;

public class GuavaPredicateExample {
    public static void main(String[] args) {
        List<Integer> numbers = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Predicate<Integer> isEven = new Predicate<Integer>() {
            @Override
            public boolean apply(Integer input) {
                return input % 2 == 0;
            }
        };

        Set<Integer> evenNumbers = Collections2.filter(numbers, isEven);
        System.out.println(evenNumbers);
    }
}

(四) Apache Commons Collections

  • 简介:Apache Commons Collections是一个处理集合相关功能的工具库,它提供了org.apache.commons.collections4.Predicate接口来进行集合元素的条件判断和过滤。
  • 特点:该Predicate接口定义了evaluate方法用于对对象进行条件评估,返回一个布尔值表示是否满足条件。与Java标准库和Guava的Predicate不同的是,它在设计上更侧重于与Apache Commons Collections中的各种集合类和工具方法配合使用,以提供更强大的集合处理功能。
  • 示例
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import java.util.ArrayList;
import java.util.List;

public class CommonsCollectionsPredicateExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);

        Predicate<Integer> isGreaterThanThree = new Predicate<Integer>() {
            @Override
            public boolean evaluate(Integer object) {
                return object > 3;
            }
        };

        List<Integer> filteredNumbers = (List<Integer>) CollectionUtils.select(numbers, isGreaterThanThree);
        System.out.println(filteredNumbers);
    }
}

(五) Hibernate Validator

  • 简介:Hibernate Validator是用于JavaBean验证的框架,它基于Java Bean Validation (JSR 380)规范实现。在Hibernate Validator中,虽然没有直接名为Predicate的接口,但验证约束的概念与Predicate类似,用于对对象的属性或整个对象进行条件验证和约束检查。
  • 特点:通过在JavaBean的属性上添加各种验证注解,如@NotNull@Size@Pattern等,Hibernate Validator可以根据这些注解定义的规则对对象进行验证。这些验证注解实际上可以看作是一种预定义的Predicate,用于判断对象的属性是否满足特定的条件。在验证过程中,Hibernate Validator会根据这些注解所对应的验证逻辑对对象进行检查,并返回验证结果。
  • 示例
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;

public class HibernateValidatorExample {
    public static void main(String[] args) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        User user = new User(null, "invalid_email", 15);

        Set<ConstraintViolation<User>> violations = validator.validate(user);
        for (ConstraintViolation<User> violation : violations) {
            System.out.println(violation.getPropertyPath() + " " + violation.getMessage());
        }
    }
}

class User {
    @javax.validation.constraints.NotNull
    private String name;

    @javax.validation.constraints.Email
    private String email;

    @javax.validation.constraints.Min(18)
    private int age;

    public User(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }

    // getters and setters
}

(六) Eclipse Collections

  • 简介:Eclipse Collections是一个高性能、功能丰富的Java集合框架,它提供了org.eclipse.collections.api.block.predicate.Predicate接口来支持集合元素的条件判断和过滤操作。
  • 特点:与其他类似的Predicate接口相比,Eclipse Collections的Predicate接口更注重与自身的集合类型和操作方法的紧密集成,以提供高效、便捷的集合处理功能。它提供了多种方式来创建和组合Predicate,并且在集合的筛选、匹配等操作中具有较好的性能表现。
  • 示例
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.impl.factory.Lists;

import java.util.List;

public class EclipseCollectionsPredicateExample {
    public static void main(String[] args) {
        MutableList<Integer> numbers = Lists.mutable.with(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Predicate<Integer> isOdd = new Predicate<Integer>() {
            @Override
            public boolean accept(Integer integer) {
                return integer % 2!= 0;
            }
        };

        MutableList<Integer> oddNumbers = numbers.select(isOdd);
        System.out.println(oddNumbers);
    }
}

这些库或框架中的Predicate接口或类似概念都为开发者提供了方便的条件判断和过滤机制,虽然它们在具体的设计和使用方式上有所不同,但都旨在帮助开发者更高效地处理数据和对象的条件验证、筛选等操作。在实际开发中,可以根据项目的具体需求和所使用的技术栈选择合适的库和方法来实现相应的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值