Java8引入函数式接口(关于函数式接口,可以戳 ),同时在JDK中也内置了大量非常好用的函数式接口,它们的存在能让你的编码生涯更加轻松。实际上用过Google Guava库的童鞋应该就相当有体会,本文就花一分钟阐述Predicates的用法
一、应用场景描述
在实际项目中,经常会遇到从一个集合中依据某种过滤条件筛选出合适的对象,然后放入一个新的集合中,例如有个猫类:
public class Cat {
private String name;
private Integer type;
private Integer age;
// set get 忽略
}
然后我们有一个猫的集合:
Listcats = new ArrayList<>();
现在我们需要根据类别筛选出加菲猫,我们都这么干:
public ListgetGarfield() {
Listgarfields = new ArrayList<>();
for(Cat cat:cats) {
if(cat.getType().equals("Garfield")) {
garfields.add(cat);
}
}
return garfields;
}
过了段时间,我们又需要找出年龄大于某个年龄的猫,我们又写了个方法:
public ListgetCatsByAgeGreatThan(int age) {
Listbigcats = new ArrayList<>();
for(Cat cat:cats) {
if(cat.getAge() > 2) {
bigcats.add(cat);
}
}
}
以后可能还会有更多的查询要求出来,但所有这些代码差异及其小,仅仅只是if的条件不一样,然后你写了一堆的查询方法,坑不?
这下好了,Java8的Predicates来拯救你了,用过Google Guava库的童鞋肯定对这个词语不会陌生,这回Java把它内置到JDK了。我们来看看它是如何拯救你的。
二、了解一下Predicates
我们查看java源码不难发现,实际上Predicate就是一个函数接口,它只有一个抽象方法:
boolean test(T t);
还有三个默认实现的方法,分别实现了最常用的逻辑判断:and、or和not
接口就是如此简单,那么怎么用呢?
三、用法详解
之前,我们为了满足需求,写了一堆的查询方法,如果用Predicate,我们只需要一个方法就可以了:
public Listquery(Predicate predicate) {
Listresult = new ArrayList<>();
for(Cat cat:cats) {
if(predicate.test(cat)) {
result.add(cat);
}
}
return result;
}
然后我们可以这么查询加菲猫:
Listgarfields = query(c -> "Garfield".equals(c.getType()));
然后这么查找大于两岁的猫:
Listgarfields = query(c -> c.getAge() > 2);
我们还可以组合条件,例如查找大于两岁的加菲猫:
Predicatep = (c) -> "Garfield".equals(c.getType());
Listgarfields = query(p.and(c -> c.getAge() > 2));
真是用过一次就爱上了有木有。
四、进一步了解
上面的阐述是我们为了阐述Predicate用法而展开的解释,实际上对于容器的过滤,Java8已经在内部就已经实现了,我们直接就可以用容器的stream来达到过滤的目的,连query方法都不用写,一句话就搞定了:
Listresult = cats.stream().filter(c -> c.getAge() > 2).collect(Collectors.toList());
注意其中的filter,filter的参数就是Predicate,哇哦,实在是太方便啦……
閱讀更多 鷹眼世界 的文章