1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.core.util;
18 
19 import android.annotation.SuppressLint;
20 
21 import java.util.Objects;
22 
23 /**
24  * Compat version of {@link java.util.function.Predicate}
25  *
26  * @param <T> the type of the input to the operation
27  */
28 @SuppressLint("UnknownNullness")
29 @SuppressWarnings("MissingNullability")
30 public interface Predicate<T> {
31 
32     /**
33      * Evaluates this predicate on the given argument.
34      *
35      * @param t the input argument
36      * @return {@code true} if the input argument matches the predicate,
37      * otherwise {@code false}
38      */
test(T t)39     boolean test(T t);
40 
41     /**
42      * Returns a composed predicate that represents a short-circuiting logical
43      * AND of this predicate and another.  When evaluating the composed
44      * predicate, if this predicate is {@code false}, then the {@code other}
45      * predicate is not evaluated.
46      *
47      * <p>Any exceptions thrown during evaluation of either predicate are relayed
48      * to the caller; if evaluation of this predicate throws an exception, the
49      * {@code other} predicate will not be evaluated.
50      *
51      * @param other a predicate that will be logically-ANDed with this
52      *              predicate
53      * @return a composed predicate that represents the short-circuiting logical
54      * AND of this predicate and the {@code other} predicate
55      * @throws NullPointerException if other is null
56      */
57     @SuppressLint("MissingNullability")
and(@uppressLint"MissingNullability") Predicate<? super T> other)58     default Predicate<T> and(@SuppressLint("MissingNullability") Predicate<? super T> other) {
59         Objects.requireNonNull(other);
60         return (t) -> test(t) && other.test(t);
61     }
62 
63     /**
64      * Returns a predicate that represents the logical negation of this
65      * predicate.
66      *
67      * @return a predicate that represents the logical negation of this
68      * predicate
69      */
70     @SuppressLint("MissingNullability")
negate()71     default Predicate<T> negate() {
72         return (t) -> !test(t);
73     }
74 
75     /**
76      * Returns a composed predicate that represents a short-circuiting logical
77      * OR of this predicate and another.  When evaluating the composed
78      * predicate, if this predicate is {@code true}, then the {@code other}
79      * predicate is not evaluated.
80      *
81      * <p>Any exceptions thrown during evaluation of either predicate are relayed
82      * to the caller; if evaluation of this predicate throws an exception, the
83      * {@code other} predicate will not be evaluated.
84      *
85      * @param other a predicate that will be logically-ORed with this
86      *              predicate
87      * @return a composed predicate that represents the short-circuiting logical
88      * OR of this predicate and the {@code other} predicate
89      * @throws NullPointerException if other is null
90      */
91     @SuppressLint("MissingNullability")
or(@uppressLint"MissingNullability") Predicate<? super T> other)92     default Predicate<T> or(@SuppressLint("MissingNullability") Predicate<? super T> other) {
93         Objects.requireNonNull(other);
94         return (t) -> test(t) || other.test(t);
95     }
96 
97     /**
98      * Returns a predicate that tests if two arguments are equal according
99      * to {@link Objects#equals(Object, Object)}.
100      *
101      * @param <T>       the type of arguments to the predicate
102      * @param targetRef the object reference with which to compare for equality,
103      *                  which may be {@code null}
104      * @return a predicate that tests if two arguments are equal according
105      * to {@link Objects#equals(Object, Object)}
106      */
107     @SuppressLint("MissingNullability")
isEqual(@uppressLint"MissingNullability") Object targetRef)108     static <T> Predicate<T> isEqual(@SuppressLint("MissingNullability") Object targetRef) {
109         return (null == targetRef)
110                 ? object -> Objects.isNull(object)
111                 : object -> targetRef.equals(object);
112     }
113 
114     /**
115      * Returns a predicate that is the negation of the supplied predicate.
116      * This is accomplished by returning result of the calling
117      * {@code target.negate()}.
118      *
119      * @param <T>    the type of arguments to the specified predicate
120      * @param target predicate to negate
121      * @return a predicate that negates the results of the supplied
122      * predicate
123      * @throws NullPointerException if target is null
124      */
125     @SuppressWarnings("unchecked")
126     @SuppressLint("MissingNullability")
not(@uppressLint"MissingNullability") Predicate<? super T> target)127     static <T> Predicate<T> not(@SuppressLint("MissingNullability") Predicate<? super T> target) {
128         Objects.requireNonNull(target);
129         return (Predicate<T>) target.negate();
130     }
131 }
132