Java8-6-Predicate接口详解

上一篇咱们学习了Function和BiFunction函数式接口,本篇继续了解下其余经常使用的函数式接口。
先来看下Predicate
Predicate函数式接口的主要做用就是提供一个test方法,接受一个参数返回一个布尔类型,Predicate在stream api中进行一些判断的时候很是经常使用。segmentfault

@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
}

使用泛型T指定传入的参数类型,咱们经过一个根据不一样条件取出不一样数据的例子来看下Predicate具体应用api

public class PredicateTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        PredicateTest predicateTest = new PredicateTest();
        //输出大于5的数字
        List<Integer> result = predicateTest.conditionFilter(list, integer -> integer > 5);
        result.forEach(System.out::println);
        System.out.println("-------");
        //输出大于等于5的数字
        result = predicateTest.conditionFilter(list, integer -> integer >= 5);
        result.forEach(System.out::println);
        System.out.println("-------");
        //输出小于8的数字
        result = predicateTest.conditionFilter(list, integer -> integer < 8);
        result.forEach(System.out::println);
        System.out.println("-------");
        //输出全部数字
        result = predicateTest.conditionFilter(list, integer -> true);
        result.forEach(System.out::println);
        System.out.println("-------");
    }
    //高度抽象的方法定义,复用性高
    public List<Integer> conditionFilter(List<Integer> list, Predicate<Integer> predicate){
        return list.stream().filter(predicate).collect(Collectors.toList());
    }
}

咱们只定义了一个conditionFilter方法,stream()会将当前list做为源建立一个Stream对象,collect(Collectors.toList())是将最终的结果封装在ArrayList中(这部分会在后续stream学习中详细介绍,这里只关注filter便可),filter方法接收一个Predicate类型参数用于对目标集合进行过滤。里面并无任何具体的逻辑,提供了一种更高层次的抽象化,咱们能够把要处理的数据和具体的逻辑经过参数传递给conditionFilter便可。理解了这种设计思想后,再看上面的例子就很容易理解,自己逻辑并不复杂,分别取出小于五、大于等于五、小于8的元素,最后一个老是返回true的条件意味着打印出集合中全部元素。
除此以外,Predicate还提供了另外三个默认方法和一个静态方法函数

default Predicate<T> and(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
}

default Predicate<T> or(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
}

default Predicate<T> negate() {
    return (t) -> !test(t);
}

static <T> Predicate<T> isEqual(Object targetRef) {
    return (null == targetRef)
            ? Objects::isNull
            : object -> targetRef.equals(object);
}

and方法接收一个Predicate类型,也就是将传入的条件和当前条件以而且的关系过滤数据。or方法一样接收一个Predicate类型,将传入的条件和当前的条件以或者的关系过滤数据。negate就是将当前条件取反。看下具体使用方式学习

public List<Integer> conditionFilterNegate(List<Integer> list, Predicate<Integer> predicate){
    return list.stream().filter(predicate.negate()).collect(Collectors.toList());
}

public List<Integer> conditionFilterAnd(List<Integer> list, Predicate<Integer> predicate,Predicate<Integer> predicate2){
    return list.stream().filter(predicate.and(predicate2)).collect(Collectors.toList());
}

public List<Integer> conditionFilterOr(List<Integer> list, Predicate<Integer> predicate,Predicate<Integer> predicate2){
    return list.stream().filter(predicate.or(predicate2)).collect(Collectors.toList());
}

//大于5而且是偶数
result = predicateTest.conditionFilterAnd(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//6 8 10
System.out.println("-------");

//大于5或者是偶数
result = predicateTest.conditionFilterOr(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//2 4 6 8 9 10
System.out.println("-------");

//条件取反
result = predicateTest.conditionFilterNegate(list,integer2 -> integer2 > 5);
result.forEach(System.out::println);// 1 2 3 4 5
System.out.println("-------");

咱们分别借助Predicate的三个默认方法定义了conditionFilterAnd、conditionFilterOr和conditionFilterNegate方法。而后再下方调用这三个方法,根据传入的判断条件观察输出结果。ui

最后再来看一下Predicate接口中的惟一一个静态方法,Java8中接口中除了增长了默认方法也能够定义静态方法。this

/**
 * Returns a predicate that tests if two arguments are equal according
 * to {@link Objects#equals(Object, Object)}.
 *
 * @param <T> the type of arguments to the predicate
 * @param targetRef the object reference with which to compare for equality,
 *               which may be {@code null}
 * @return a predicate that tests if two arguments are equal according
 * to {@link Objects#equals(Object, Object)}
 */
static <T> Predicate<T> isEqual(Object targetRef) {
    return (null == targetRef)
            ? Objects::isNull
            : object -> targetRef.equals(object);
}

isEqual方法返回类型也是Predicate,也就是说经过isEqual方法获得的也是一个用来进行条件判断的函数式接口实例。而返回的这个函数式接口实例是经过传入的targetRef的equals方法进行判断的。咱们看一下具体用法lua

System.out.println(Predicate.isEqual("test").test("test"));//true

这里会用第一个"test"的equals方法判断与第二个"test"是否相等,结果true。设计

下一篇code

相关文章
相关标签/搜索