Predicate是Guava提供的基础接口,该接口包含一个带有泛型参数的方法,该方法输入一个范型,输入一个布尔值,是一个典型的谓词函数(谓词函数:输入一个对象,返回true或者false),定义如下:
public interface Predicate<T> {
...
boolean apply(@Nullable T input);
...
}
采用谓词函数的思想,利用传入到函数内的谓词的调用代替if语句里的硬编码的判断条件。如果函数接受一个泛型参数,这意味着,只需要编写一遍带有谓词函数作为参数的方法,就可以覆盖所有的应用场景。范例如下:
定义简单POJO类:
@Data
public class ClassC {
private int age;
private Date birthDay;
ClassC(int age, Date birthDay) {
this.age = age;
this.birthDay = birthDay;
}
}
用谓词函数替换if条件,定义公共集合筛选方法,并根据不同的筛选条件过滤集合。
public class Test {
@Test
public void testPredicate() {
List<ClassC> classCS = Lists.newArrayList(new ClassC(11, DateUtils.addDays(new Date(), 10)), new ClassC(21, DateUtils.addDays(new Date(), -20)), new ClassC(31, DateUtils.addDays(new Date(), -30)));
List<ClassC> ageSelections = filterCondition(classCS, new Predicate<ClassC>() {
public boolean apply(ClassC input) {
return input.getAge() > 20;
}
});
System.out.println(ageSelections);
List<ClassC> birthDaySelections = filterCondition(classCS, new Predicate<ClassC>() {
public boolean apply(ClassC input) {
return input.getBirthDay().after(new Date());
}
});
System.out.println(birthDaySelections);
}
// 按条件过滤ClassC集合
private List<ClassC> filterCondition(List<ClassC> classCS, Predicate<ClassC> condition) {
final List<ClassC> results = Lists.newArrayList();
for(ClassC classC : classCS) {
if(condition.apply(classC)) {
results.add(classC);
}
}
return results;
}
}
Guava提供了许多简化预言设置的静态工具方法,封装在Predicates类中,结合这些静态方法可以实现自己的谓词函数。
...
@org.junit.Test
public void testPredicate() {
// 判断整数是否为0
Predicate<Integer> isZero = Predicates.equalTo(0);
Assert.assertTrue(isZero.apply(0));
Assert.assertFalse(isZero.apply(1));
// 判断字符串是否包含a
Predicate<CharSequence> containA = Predicates.containsPattern("a");
Assert.assertTrue(containA.apply("abc"));
Assert.assertFalse(containA.apply("def"));
// 判断是否包含在整数集合内
Predicate<Integer> ins = Predicates.in(Lists.newArrayList(22, 33, 44));
Assert.assertTrue(ins.apply(22));
Assert.assertFalse(ins.apply(55));
// 判断对象非空
Predicate<Object> isNotNull = Predicates.notNull();
Assert.assertTrue(isNotNull.apply(Integer.MAX_VALUE));
Assert.assertFalse(isNotNull.apply(null));
// 判断对象为空
Predicate<Object> isNull = Predicates.isNull();
Assert.assertTrue(isNull.apply(null));
Assert.assertFalse(isNull.apply(Integer.MAX_VALUE));
// 判断对象是String的实例
Predicate<Object> isString = Predicates.instanceOf(String.class);
Assert.assertTrue(isString.apply("abc"));
Assert.assertFalse(isString.apply(Integer.MAX_VALUE));
// 判断是否与Object类相等或是其超类
Predicate<Class<?>> isAssignableFrom = Predicates.assignableFrom(Object.class);
Assert.assertTrue(isAssignableFrom.apply(String.class));
Assert.assertFalse(isAssignableFrom.apply(Object.class));
}
...
对于给定的谓词,可以取非:
...
// 不为0
Predicate<Integer> isNotZero = Predicates.not(Predicates.equalTo(0));
Assert.assertTrue(isNotZero.apply(1));
Assert.assertFalse(isNotZero.apply(0));
...
利用or、and操作符可以连接多个谓词:
...
// 为空或为0
Predicate<Integer> isNullOrZero = Predicates.or(Predicates.<Integer>isNull(), Predicates.equalTo(0));
Assert.assertTrue(isNullOrZero.apply(null));
Assert.assertTrue(isNullOrZero.apply(0));
Assert.assertFalse(isNullOrZero.apply(1));
// 是否包含在两个整数集合的交集内
Predicate<Integer> andIns = Predicates.and(Predicates.in(Lists.newArrayList(22, 33)), Predicates.in(Lists.newArrayList( 33, 44)));
Assert.assertTrue(andIns.apply(33));
Assert.assertFalse(andIns.apply(44));
...
当然也可以定义固定的特殊谓词(只返回true在逻辑学中成为永真式,只返回false称为永假式):
...
// 永真
Predicates.alwaysTrue();
// 永假
Predicates.alwaysFalse();
...