Predicate是个断言接口(给定lambda表达式,返回boolean值)
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
// &&
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
// !
default Predicate<T> negate() {
return (t) -> !test(t);
}
// ||
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
以上方法都返回Predicate对象,意味着可以支持链式调用,例如:
Predicate p1 = o -> o.equals(a);
Predicate p2 = o -> o.equals(b);
Predicate p3 = o -> o.equals(c);
somelist.stream().filter(p1.and(p2).or(p3)).collect(Collectors.toList());
使用场景:
缓存中有一份List,页面查询该list,并需支持多条件动态过滤。
//模拟缓存数据
//假设有name,age,height等条件
List<User> userList = cache.get();
Predicate expressAll = null;
if(StringUtils.isNotBlank(name)){
expressAll = user -> Objects.equals(user.getName(),name);
}
if(Objects.nonNull(age)){
Predicate express = user -> Objects.equals(user.getAge(),age);
if (Objects.isNull(expressAll)) {
expressAll = express;
} else {
expressAll = expressAll.and(express);
}
}
if(StringUtils.isNotBlank(height)){
Predicate express = user -> Objects.equals(user.getHeight(),height);
if (Objects.isNull(expressAll)) {
expressAll = express;
} else {
expressAll = expressAll.and(express);
}
}
if(Objects.isNull(expressAll)){
userList = userList.stream().filter(expressAll).collect(Collectors.toList());
}
这样就像动态拼接sql一样,完成了动态拼接查询条件。