zoukankan      html  css  js  c++  java
  • java代码(13) ---Predicate详解


    Predicate详解


    遇到Predicate是自己在自定义Mybatis拦截器的时候,在拦截器中我们是通过反射机制获取对象的所有属性,在查看这些属性上是否有我们自定义的UUID注解

    如果有该注解,那么就给该属性赋值UUID随机字符串,作为主键保存到数据库,所以前提条件是获取带有UUID注解的属性,就需要用到Predicate

        //获取所有带有UUID注解的属性
        Set<Field> allFields = ReflectionUtils.getFields(object.getClass(),x.getAnnotation(UUId.class)!=null);

    也想到之前自己在用steam处理集合的时候,添加的过滤条件也是用Predicate,只不过它们不在同一包下,虽然它们不在同一包下但它们的作用是一致的,就是

    Predicate接口主要用来判断一个参数是否符合要求

    下面对这两个接口分别进行说明并举例

    一、java.util.function.Predicate

    1、接口源码

    @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);
        }
    }

    2、常规示例

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

    3、集合Stream示例

    User对象

    @Data
    @AllArgsConstructor
    @ToString
    public class User {
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 性别
         */
        private String sex;
    
        /**
         * 年龄
         */
        private Integer age;
        
       /**
         * 重写equals和hashCode
         */
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof User) {
                User user = (User) obj;
                if (name.equals(user.name)){
                    return true;
                }
            }
                return false;
            }
            @Override
            public int hashCode () {
                return name.hashCode();
            }
    
        }

     测试代码

     public static void main(String[] args) {
            User user1 = new User("张三", "女", 1);
            User user2 = new User("李四", "男", 2);
            User user3 = new User("张三", "女", 3);
            List<User> users = Lists.newArrayList(user1, user2, user3);
            /**
             * 1、获取年龄大于2的对象
             */
            List<User> userList = users.stream().filter(x -> x.getAge() > 2).collect(Collectors.toList());
            System.out.println(userList);//[User(name=张三, sex=女, age=3)]
            /**
             * 2、去重 设置name即为相同对象
             */
            //方式1直接使用distinct
            List<User> userList1 = users.stream().filter(distinctByName(item->item.getName())).collect(Collectors.toList());
            System.out.println(userList1);
    
            /**
             * 3.从集合找出与该对象相同的元素
             */
            User user4=new User("张三","男",1);
            Predicate<User> predicate = Predicate.isEqual(user4);
            List<User>  collect2=users.stream().filter(predicate).collect(Collectors.toList());
            System.out.println(collect2);
        }
        private static <T> Predicate<T> distinctByName(Function<? super T , Object> keyExtractor) {
                 Map<Object , Boolean> seen = new ConcurrentHashMap<>();
                 return t -> seen.putIfAbsent(keyExtractor.apply(t),Boolean.TRUE) ==null;
        }

    运行结果:

     二、com.google.common.base.Predicate

    这里的Predicate是配合guava使用的

    作用:

      1.处理集合的过滤条件

      2.反射工具类的过滤条件

    1、接口源码

    @GwtCompatible
    public interface Predicate<T> {
      //重写过滤条件
      @CanIgnoreReturnValue
      boolean apply(@Nullable T input);
      //重写equals
      boolean equals(@Nullable Object object);

    在使用它时需要重写两个方法

    2、示例

    自定义UUID注解

    @Data
    @AllArgsConstructor
    @ToString
    public class Person {
        /**
         * 姓名在name上使用UUID注解
         */
        @UUID
        private String name;
        private Integer age;
        private String sex;
    }
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface UUID {
    }

    测试代码

    public static void main(String[] args) {
            Person person1 = new Person("张三", 1, "女");
            Person person2 = new Person("李四", 2, "男");
            Person person3 = new Person("张三", 3, "女");
            List<Person> list = Lists.newArrayList(person1,person2,person3);
            /**
             * 1.guava使用过滤年龄大于2的
             */
            Predicate<Person> predicate1=new Predicate<Person>(){
    
                @Override
                public boolean apply(Person input) {
                    if (input.getAge()>2){
                        return true;
                    }
                    return false;
                }
                @Override
                public boolean equals(Object object){
                    return true;
                }
            };
            list= Lists.newArrayList(Iterables.filter(list,predicate1));
            System.out.println("过滤后的回合数据:"+list);
          /**
         * 2.配合反射工具类ReflectionUtils过滤获取属性
         */
        Person person4 = new Person("张三", 1, "女");
        Set<Field> allFields= ReflectionUtils.getFields(person4.getClass(),x->x!=null && x.getAnnotation(UUID.class)!=null);
        System.out.println("带UUID注解的属性有"+allFields);
      }

    运行结果:

  • 相关阅读:
    HDU3371--Connect the Cities
    HDU1232--畅通工程
    HDU1102--Constructing Roads
    HDU1856--More is better
    HDU1325--Is It A Tree?
    HDU1272--小希的迷宫
    HDU1213--How Many Tables
    lnmp 实现owncloud
    lemp 编译安装 不完整版
    dns 视图
  • 原文地址:https://www.cnblogs.com/zhenbian/p/12981829.html
Copyright © 2011-2022 走看看