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);
}
運行結果: