目录
一、分别简单介绍下
(一)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
,只有当两个Predicate
的test
方法都返回true
时,新的Predicate
的test
方法才返回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框架中用于构建查询条件的核心接口之一,它提供了一系列方法来创建、组合和操作查询条件,以下是对其主要方法的介绍:
- 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();
}
}
- 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();
}
}
- 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();
}
}
- 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();
}
}
- 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();
}
}
- 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
,如and
、or
、not
等方法,这些方法与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
接口或类似概念都为开发者提供了方便的条件判断和过滤机制,虽然它们在具体的设计和使用方式上有所不同,但都旨在帮助开发者更高效地处理数据和对象的条件验证、筛选等操作。在实际开发中,可以根据项目的具体需求和所使用的技术栈选择合适的库和方法来实现相应的功能。