Guava谓词函数 - Predication&Predications

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();
...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值