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

運行結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM