Pedicate的使用

Pedicate

源码解释:

/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #test(Object)}.
 *
 * @param <T> the type of the input to the predicate
 *
 * @since 1.8
 */

解释一下

1 . 代表着一个**“断定式子”**

2 . 这是一个实用的接口—>其中的实用方法指的是test方法

    /**
     * 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);

test方法的作用是:

  • 1 . 评估参数里面的表达式(说白了就是验证传进来的参数符不符合规则,后面有例子)
  • 2 . 它的返回值是一个boolean类型(这点需要注意一下)。
@Test
    public void predicate1() {
        Predicate<String> predicate = (String s) -> {
            return s.equals("answer");
        };
        System.out.println(predicate.test("problem"));
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println(predicate.test("answer"));
    }
    
得到结果:  
false
~~~~~~~~~~~~~~~~~~~~~~~~~
true

在这个代码里面:我们可以看得出来test()方法体里面判断的是:传进来的参数s是否等于answer,而answer这个对象是由外部调用传进来的。

但是这个样子违反了1.8的新特性—>函数式编程即:我们需要做到的是将函数作为参数,“说白了就是写更少的代码做更多的事”。,我们这个貌似做不到,如果我们要判断,传入的参数长度是否大于5或者说判断传入的参数是否为奇数或者偶数呢?难道我们还要像以前一样写出多个参数么?当然,不是如果继续那样做,Java8的出现将毫无意义!

下面我们来将上面的问题处理一下:(采用传统的方式和新的方式)

  • 1.判断传入的字符串的长度是否大于5
  • 2.判断传入的参数是否是偶数
  • 3.判断数字是否大于10
 /**
   * 判断传入的字符串的长度是否大于5
 */
@Test
public void predicate2() {
  String input = "problem";
  //传统方法
  System.out.println("元素方法,定义一个utils调用:" + judgeStringLength(input));
  //predicate方法
  System.out.println(judgeConditionByFunction("problem", value -> value.length() > 5));
}

    public boolean judgeStringLength(String judgeString) {
        return judgeString.length() > 5 ? true : false;
    }

    public boolean judgeConditionByFunction(String value, Predicate<String> predicate) {
        return predicate.test(value);
    }

接口源码

@FunctionalInterface
public interface Predicate<T> {
    /**
     * 具体过滤操作 需要被子类实现.
     * 用来处理参数T是否满足要求,可以理解为 条件A
     */
    boolean test(T t);
    /**
     * 调用当前Predicate的test方法之后再去调用other的test方法,相当于进行两次判断
     * 可理解为 条件A && 条件B
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    /**
     * 对当前判断进行"!"操作,即取非操作,可理解为 ! 条件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);
    }
}

示例演示

@Test
    public void predicate3() {
        /**
         * 1、判断数字是否大于7
         */
        //设置一个大于7的过滤条件
        Predicate<Integer> predicate = x -> x > 7;
        //输出 true
        System.out.println(predicate.test(10));
        //输出 fasle
        System.out.println(predicate.test(6));
        /**
         * 2、大于7并且
         */
        //在上面大于7的条件下,添加是偶数的条件
        predicate = predicate.and(x -> x % 2 == 0);
        //输出 fasle
        System.out.println(predicate.test(6));
        //输出 true
        System.out.println(predicate.test(12));
        //输出 fasle
        System.out.println(predicate.test(13));
        /**
         * 3、add or 简化写法
         */
        predicate = x -> x > 5 && x < 9;
        //输出 false
        System.out.println(predicate.test(10));
        //输出 true
        System.out.println(predicate.test(6));
    }

练习题

/**
     * 请在测试类main方法中完成以下需求
     * 已知有Integer[] arr = {-12345, 9999, 520, 0,-38,-7758520,941213}
     * a) 使用lambda表达式创建Predicate对象p1,p1能判断整数是否是自然数(大于等于0)
     * b) 使用lambda表达式创建Predicate对象p2,p2能判断整数的绝对值是否大于100
     * c) 使用lambda表达式创建Predicate对象p3,p3能判断整数是否是偶数
     * <p>
     * 遍历arr,仅利用已创建的Predicate对象(不使用任何逻辑运算符),完成以下需求
     * i. 打印自然数的个数
     * ii. 打印负整数的个数
     * iii. 打印绝对值大于100的偶数的个数
     * iv. 打印是负整数或偶数的数的个数
     */
    @Test
    public void predicate4() {
        Predicate<Integer> p1 = x -> x >= 0;
        Predicate<Integer> p2 = x -> Math.abs(x) > 100;
        Predicate<Integer> p3 = x -> x % 2 == 0;
        Integer[] arr = {-12345, 9999, 520, 0, -38, -7758520, 941213};
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        int count4 = 0;
        for (Integer item : arr) {
            //统计自然数个数
            if (p1.test(item)){
                count1++;
            }
            //统计负整数个数
            if (p1.negate().test(item)){
                count2++;
            }
            //统计绝对值大于100的偶数个数
            if (p2.and(p3).test(item)){
                count3++;
            }
            //统计是负整数或偶数的数的个数
            if (p1.negate().or(p3).test(item)){
                count4++;
            }
        }
        //分别打印结果
        System.out.println("自然数的个数为:"+count1);
        System.out.println("负整数的个数为:"+count2);
        System.out.println("绝对值大于100的偶数的个数为:"+count3);
        System.out.println("是负整数或偶数的数的个数为:"+count4);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值