JDK中Predicate接口源码解析和使用详解
Posted 秋9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK中Predicate接口源码解析和使用详解相关的知识,希望对你有一定的参考价值。
目录
1.Predicate接口简介
Predicate接口表示一个参数的谓词,是一个布尔值函数。
- JDK8 新增的函数式接口,提供一个抽象方法test, 接受一个参数, 根据这个参数进行一些判断, 返回判断结果 true / false
- 提供4个默认的default方法, 即and, or, negate,isEqual 用于进行组合判断
- 在流stream中被广泛使用
2.Predicate接口源码阅读
JDK中Predicate接口源码,位置在jdk的src.zip文件中的java.util.function.Predicate.java文件,
详细如下。
package java.util.function;
import java.util.Objects;
/**
* 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
*/
@FunctionalInterface
public interface Predicate<T> {
/**
* 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}
* 接收一个参数, 判断这个参数是否匹配某种规则, 匹配成功返回true, 匹配失败则返回false
*/
boolean test(T t);
/**
* Returns a composed predicate that represents a short-circuiting logical
* AND of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code false}, then the {@code other}
* predicate is not evaluated.
*
* <p>Any exceptions thrown during evaluation of either predicate are relayed
* to the caller; if evaluation of this predicate throws an exception, the
* {@code other} predicate will not be evaluated.
*
* @param other a predicate that will be logically-ANDed with this
* predicate
* @return a composed predicate that represents the short-circuiting logical
* AND of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null
* default方法, 接收另外一个Predicate<T>类型参数进行逻辑与操作
* 返回一个新的Predicate
* Predicate<T> newPredicate = (t) -> this.test(t) && other.test(t);
* 如果传入的Predicate为空, 会抛出空指针异常
*/
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
* Returns a predicate that represents the logical negation of this
* predicate.
*
* @return a predicate that represents the logical negation of this
* predicate
* default方法, 返回当前Predicate取反操作之后的Predicate
* Predicate<T> newPredicate = (t) -> !test(t);
*/
default Predicate<T> negate() {
return (t) -> !test(t);
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* OR of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code true}, then the {@code other}
* predicate is not evaluated.
*
* <p>Any exceptions thrown during evaluation of either predicate are relayed
* to the caller; if evaluation of this predicate throws an exception, the
* {@code other} predicate will not be evaluated.
*
* @param other a predicate that will be logically-ORed with this
* predicate
* @return a composed predicate that represents the short-circuiting logical
* OR of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null
* default方法, 接收另外一个Predicate<T>类型参数进行逻辑或操作
* 返回一个新的Predicate
* Predicate<T> newPredicate = (t) -> this.test(t) || other.test(t);
* 如果传入的Predicate为空, 会抛出空指针异常
*/
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
* Returns a predicate that tests if two arguments are equal according
* to {@link Objects#equals(Object, Object)}.
*
* @param <T> the type of arguments to the predicate
* @param targetRef the object reference with which to compare for equality,
* which may be {@code null}
* @return a predicate that tests if two arguments are equal according
* to {@link Objects#equals(Object, Object)}
* 接收一个Object targetRef, 返回一个Predicate<T>类型
* 返回的Predicate的test方法是用来判断传入的参数是否等于targetRef
* 如Predicate<T> predicate = Predicate.isEqual("demo");
* 等同于Predicate<T> predicate = t -> "demo".equals(t);
*/
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
3.Predicate接口各方法使用举例
public class PredicateTest {
// 辅助打印方法
private static void print(Object obj) {
System.out.println(obj);
}
public static void main(String[] args) {
String demeStr="中国";
Predicate<String> predicate = item -> demeStr.equals(item);
// 1. test 方法测试
print("1---> " + predicate.test(demeStr));
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
// 2. Predicate 返回一个List中的偶数
// list.stream(), 表示将List作为流进行处理, filter()方法接收一个Predicate, toArray是将流转换成数组
Object[] result = list.stream().filter(t -> t % 2 == 0).toArray();
print("2---> " + Arrays.toString(result));
// 3. 测试Predicate的and方法, 打印list中大于3, 小于6的数字
Predicate<Integer> predicate1 = t -> t > 3;
predicate1 = predicate1.and(t -> t < 6);
result = list.stream().filter(predicate1).toArray();
print("3---> " + Arrays.toString(result));
// 4. 测试Predicate的or方法, 打印list中小于3或大于5的数字
predicate1 = t -> t < 3;
predicate1 = predicate1.or(t -> t > 5);
result = list.stream().filter(predicate1).toArray();
print("4---> " + Arrays.toString(result));
// 5. 测试Predicate的negate方法, 返回list中大于等于3,小于等于5的数字, 即对场景4取反
result = list.stream().filter(predicate1.negate()).toArray();
print("5---> " + Arrays.toString(result));
// 6. 测试静态方法isEqual方法, 个人感觉这个方法没啥用处
predicate = Predicate.isEqual(demeStr);
print("6---> " + predicate.test(demeStr));
print("6---> " + predicate.test(demeStr+"1"));
}
}
运行结果如下:
4.Predicate接口工作运用
/**
* 所有的数: 1, 2, 3, 4, 5, 6, 7, 8, 9,
* 奇数: 1, 3, 5, 7, 9,
* 大于6的数: 7, 8, 9,
*/
public static void main(String args[]){
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
System.out.print("所有的数: ");
eval(list, n -> true);
System.out.print("\\n奇数: ");
eval(list, n-> n%2 == 1 );
System.out.print("\\n大于6的数: ");
eval(list, n -> n > 6 );
}
private static void eval(List<Integer> list, Predicate<Integer> predicate) {
list.stream().filter( n -> predicate.test(n)).forEach(e -> System.out.print(e+","));
}
运行结果为:
以上是关于JDK中Predicate接口源码解析和使用详解的主要内容,如果未能解决你的问题,请参考以下文章