OK,不废话,先来简单看一下Predicate这个接口。
package java.util.function;
import java.util.Objects;
/**
* @since 1.8
*/
@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);
}
}
该接口有一个抽象方法,三个默认方法,一个静态方法。对于拥有唯一抽象方法的函数式接口,我们可以使用lamda表达式来进行实现。接下来我们就一个个接口的来解析。
首先我们来看一下test方法。
//函数式抽象接口,需要提供实现体,返回boolean类型参数。
boolean test(T t);
接下来我们写个小demo跑一下
public class PredicateTest {
public static void main(String[] args) {
Predicate<Integer> predicateInt = x -> x > 10;
Predicate<String> predicateStr = r -> r.length() > 10;
System.out.println("第一个Predicate的测试,测试数值是否大于10,结果为:" + predicateInt.test(11));
System.out.println("第二个Predicate的测试,测试字符串的长度是否大于10,结果为:" + predicateStr.test("test"));
}
}
运行结果:
第一个Predicate的测试,测试数值是否大于10,结果为:true
第二个Predicate的测试,测试字符串的长度是否大于10,结果为:false
默认方法negate()
// 返回与当前Predicate对象具有相反test抽象接口实现的Predicate对象
default Predicate<T> negate() {
return (t) -> !test(t);//返回一个函数式实现
}
public static void main(String[] args) {
Predicate<Integer> predicateInt = x -> x > 10;
Predicate<String> predicateStr = r -> r.length() > 10;
System.out.println("第一个Predicate的测试,测试数值是否大于10,结果为:" + predicateInt.test(11));
System.out.println("第二个Predicate的测试,测试字符串的长度是否大于10,结果为:" + predicateStr.test("test"));
System.out.println("第一个Predicate的【negate方法】测试,测试数值是否大于10,结果为:" + predicateInt.negate().test(11));
System.out.println("第二个Predicate的【negate方法】测试,测试字符串的长度是否大于10,结果为:" + predicateStr.negate().test("test"));
}
结果:
第一个Predicate的测试,测试数值是否大于10,结果为:true
第二个Predicate的测试,测试字符串的长度是否大于10,结果为:false
第一个Predicate的【negate方法】测试,测试数值是否大于10,结果为:false
第二个Predicate的【negate方法】测试,测试字符串的长度是否大于10,结果为:true
下面简单解析一下剩下的默认方法
/**
* 返回一个和other的test方法实现进行与操作的Predicate对象
*/
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
System.out.println("第一个Predicate的【and方法】测试,测试数值是否大于10小于20,结果为:" + predicateInt.and(x->x<20).test(11));
结果:true
/**
* 返回一个和other的test方法实现进行或操作的Predicate对象
*/
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
System.out.println("第一个Predicate的【or方法】测试,测试数值是否大于10或小于5,结果为:" + predicateInt.or(x->x<5).test(4));
结果:true
/**
* 若入参不为空,则返回一个test实现为判断是否相等的Predicate对象
*/
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
System.out.println(Predicate.isEqual(11).test(12));
结果:false
Predicate这个接口的用处就是函数式编程实现,以及在test中实现自己需要的判断逻辑,代码量减少了,代码所展现逻辑更加清晰了。最大的优势就是作为方法的函数式入参,可以灵活的修改方法的入参实现,应对变化的需求。
比如:
//过滤年龄超过30岁的人,并添加到result集中。这里我们如果有新的需求,比如超过20,小于30,啥的,都只要至二级调用filter方法,传入对应的lambda表达式即可,如:filter(allPersonList, p -> p.getAge() < 30 && p.getAge() > 20)。
public void test() {
List<Person> ageGreateThanTwenty = filter(allPersonList, p -> p.getAge() >= 30);
System.out.println(ageGreateThanTwenty);
}
private List<Person> filter(List<Person> persons, Predicate<Person> predicate) {
List<Person> result = Lists.newArrayList();
for (Person person : persons) {
if (predicate.test(person)) {
result.add(person);
}
}
return result;
}
谢谢·
参考:
https://blog.csdn.net/qq_28410283/article/details/80601495
https://www.cnblogs.com/zhandouBlog/p/9383234.html