• JAVA8 - java.util.function.Predicate


    什么是谓词函数?

    谓词函数是一个判断式,一个返回BOOLEAN值的函数或者仿函数。

    谓词和函数的区别是什么?

    两者都是功能接口;
    谓词,是单个参数的函数,它返回的是BOOLEAN值,TRUE或FALSE,可用作LAMBDA表达式或方法引用的分配目标,谓词的抽象方法是test()。
    函数<T,R> 也是单个参数函数,但它返回的是一个对象,T表示函数的输入类型,R 表示返回结果的类型,函数的抽象方法是apply()。

    Predicate是什么?

    Predicate这个单词的英语含义是断言(假设),Predicate是一个功能接口,在java.util.function包中,它是一个返回值为布尔值的函数,它表示一个参数的谓词,常用作集合类型的流的过滤条件。
    在这里插入图片描述

    Predicate源码分析

    @FunctionalInterface
    public interface Predicate<T> {
        /**
         * 函数接口方法.
         * 用来处理参数T是否满足要求, 简单说用于判断一个参数是否符合某个条件, 可以理解为: 条件A
         */
        boolean test(T t);
        /**
         * 调用当前Predicate的test方法之后再去调用other的test方法, 相当于进行两次判断
         * 让前后两个Predicate判断条件一起生效,可理解为: 条件A && 条件B
         */
        default Predicate<T> and(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) && other.test(t);
        }
        /**
         * 对当前判断进行"!"操作,即取非操作,返回一个与指定判断相反的Predicate,可理解为: !条件A
         */
        default Predicate<T> negate() {
            return (t) -> !test(t);
        }
        /**
         * 对当前判断进行"||"操作,即取或操作,可以理解为: 条件A ||条件B
         */
        default Predicate<T> or(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) || other.test(t);
        }
    
        /**
         * 对当前操作进行"="操作,即取等操作,可以理解为: A == B
         */
        static <T> Predicate<T> isEqual(Object targetRef) {
            return (null == targetRef)
                    ? Objects::isNull
                    : object -> targetRef.equals(object);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    Predicate的变体

    接口名参数返回类型描述
    BiPredicate(T, U)boolean接收两个参数
    DoublePredicatedoubleboolean接收double类型的参数
    IntPredicateintboolean接收int类型的参数
    LongPredicatelongboolean接收int类型的参数

    Predicate的使用

    private void test004(){
      List<Integer> numberList = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);
    
       Predicate<Integer> lessThan5 = number -> number <= 5;
       Predicate<Integer> greaterThan9 = number -> number >= 9;
    
       // 小于等于 5
       System.out.println(numberList.stream().filter(lessThan5).collect(Collectors.toList()));
       // 大于 5
       System.out.println(numberList.stream().filter(lessThan5.negate()).collect(Collectors.toList()));
       // 小于等于 5 或者大于等于 9
       System.out.println(numberList.stream().filter(lessThan5.or(greaterThan9)).collect(Collectors.toList()));
       // ! (小于等于 5 AND 大于等于 9)
       System.out.println(numberList.stream().filter(lessThan5.and(greaterThan9).negate()).collect(Collectors.toList()));
    
       // 小于等于 5 AND ! 大于等于 9
       System.out.println(numberList.stream().filter(lessThan5.and(greaterThan9.negate())).collect(Collectors.toList()));
    
    }
    
    private void test003() {
       Predicate<String> startsWith = x -> x.startsWith("S");
       Predicate<String> contains   = x -> x.contains("m");
    
       Predicate<String> lengthgt4 = str -> str.length() > 4;
       List<Predicate<String>> allPredicates = Arrays.asList(
               startsWith,
               contains,
               lengthgt4
       );
    
       // 所有条件执行AND
       List<String> names1 = Arrays.asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
       List<String> result1 = names1.stream()
               .filter(allPredicates.stream().reduce(x -> true, Predicate::and))
               .collect(Collectors.toList());
       System.out.println("result1 = " + result1);
    
       // 所有条件执行OR
       List<String> names2 = Arrays.asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
       List<String> result2 = names2.stream()
               .filter(allPredicates.stream().reduce(x -> false, Predicate::or))
               .collect(Collectors.toList());
       System.out.println("result2 = " + result2);
    
    }
    
    private void test002() {
       List<Integer> list = Arrays.asList(1, 3, 5, 2, 4);
       System.out.println("list = " + list); // [1, 3, 5, 2, 4]
    
       Predicate<Integer> predicate = x -> x < 4;
       Predicate<Integer> predicate2 = x -> x > 1;
       // AND方法表示两个predicate过滤条件需要同时成立, 相当于&&(与)
       List<Integer> list2 = list.stream().filter(predicate.and(predicate2)).collect(Collectors.toList());
       System.out.println("list2 = " + list2); // [3, 2]
    
       Predicate<Integer> predicate3 = predicate.and(predicate2);
       // 可以直接用predicate.and(predicate2), 也可以定义一个新的predicate3
       List<Integer> list3 = list.stream().filter(predicate3).collect(Collectors.toList());
       System.out.println("list3 = " + list3); // [3, 2]
    
       Predicate<Integer> predicate4 = x -> x >= 4;
       Predicate<Integer> predicate5 = x -> x <= 1;
       // OR方法表示两个predicate过滤条件只需要成立1个, 相当于||(或)
       List<Integer> list4 = list.stream().filter(predicate4.or(predicate5)).collect(Collectors.toList());
       System.out.println("list4 = " + list4); // [1, 5, 4]
    
       // NEGATE方法表示这个predicate过滤条件不成立, 相当于!(非)
       List<Integer> list5 = list.stream().filter(predicate4.negate()).collect(Collectors.toList());
       System.out.println("list5 = " + list5); // [1, 3, 2]
    
       // TEST方法为测试单个用例, 判断参数是否满足predicate的条件, 返回值为boolean类型
       System.out.println("test-10 = " + predicate5.test(10)); // false
       System.out.println("test-1 = " + predicate5.test(1)); // true
    
       int number = 3;
       // ISEQUAL为静态方法, 用来判断集合的流中是否有与isEqual方法相等的值
       Predicate<Integer> predicate6 = Predicate.isEqual(number);
       System.out.println("equal = " + list.stream().filter(predicate6).collect(Collectors.toList())); // [3]
    
    }
    
    private void test001() {
       // 数组
       IntPredicate intPredicate = x -> x < 4;
       int[] arr = new int[]{1, 3, 5, 2, 4};
       System.out.println(Arrays.stream(arr).max().getAsInt());
       int[] arr2 = Arrays.stream(arr).filter(intPredicate).toArray();
       System.out.println(Arrays.toString(arr2));
    
       // 集合
       Predicate<Integer> predicate = x -> x < 4;
       List<Integer> list = Arrays.asList(1, 3, 5, 2, 4);
       System.out.println(list.stream().max(Integer::compareTo).get());
       List<Integer> list2 = list.stream().filter(predicate).collect(Collectors.toList());
       System.out.println(list2);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
  • 相关阅读:
    IB心理学如何记住大量的内容?
    JavaScript基础 JavaScript第二天 1. 运算符
    分布式系统中的经典思想实验——两将军问题和拜占庭将军问题
    内网穿透代理服务器nps使用初探(一)
    路由器二次开发一步一步把工业路由器变成一个高端的可指定出网、节点和链路的路由器,包含详细过程及快捷脚本(二)
    Spring-AOP入门
    NSSCTF做题(9)
    基于element-ui封装可配置表单组件
    如何确保ChatGPT的文本生成对特定行业术语的正确使用?
    C++ Reference: Standard C++ Library reference: C Library: cwchar: wcsrtombs
  • 原文地址:https://blog.csdn.net/goodjava2007/article/details/125499836