Pedicate
源码解释:
/**
* 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
*/
解释一下
1 . 代表着一个**“断定式子”**
2 . 这是一个实用的接口—>其中的实用方法指的是test方法
/**
* 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}
*/
boolean test(T t);
test方法的作用是:
- 1 . 评估参数里面的表达式(说白了就是验证传进来的参数符不符合规则,后面有例子)
- 2 . 它的返回值是一个boolean类型(这点需要注意一下)。
@Test
public void predicate1() {
Predicate<String> predicate = (String s) -> {
return s.equals("answer");
};
System.out.println(predicate.test("problem"));
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println(predicate.test("answer"));
}
得到结果:
false
~~~~~~~~~~~~~~~~~~~~~~~~~
true
在这个代码里面:我们可以看得出来test()方法体里面判断的是:传进来的参数s是否等于answer,而answer这个对象是由外部调用传进来的。
但是这个样子违反了1.8的新特性—>函数式编程即:我们需要做到的是将函数作为参数,“说白了就是写更少的代码做更多的事”。,我们这个貌似做不到,如果我们要判断,传入的参数长度是否大于5或者说判断传入的参数是否为奇数或者偶数呢?难道我们还要像以前一样写出多个参数么?当然,不是如果继续那样做,Java8的出现将毫无意义!
下面我们来将上面的问题处理一下:(采用传统的方式和新的方式)
- 1.判断传入的字符串的长度是否大于5
- 2.判断传入的参数是否是偶数
- 3.判断数字是否大于10
/**
* 判断传入的字符串的长度是否大于5
*/
@Test
public void predicate2() {
String input = "problem";
//传统方法
System.out.println("元素方法,定义一个utils调用:" + judgeStringLength(input));
//predicate方法
System.out.println(judgeConditionByFunction("problem", value -> value.length() > 5));
}
public boolean judgeStringLength(String judgeString) {
return judgeString.length() > 5 ? true : false;
}
public boolean judgeConditionByFunction(String value, Predicate<String> predicate) {
return predicate.test(value);
}
接口源码
@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);
}
}
示例演示
@Test
public void predicate3() {
/**
* 1、判断数字是否大于7
*/
//设置一个大于7的过滤条件
Predicate<Integer> predicate = x -> x > 7;
//输出 true
System.out.println(predicate.test(10));
//输出 fasle
System.out.println(predicate.test(6));
/**
* 2、大于7并且
*/
//在上面大于7的条件下,添加是偶数的条件
predicate = predicate.and(x -> x % 2 == 0);
//输出 fasle
System.out.println(predicate.test(6));
//输出 true
System.out.println(predicate.test(12));
//输出 fasle
System.out.println(predicate.test(13));
/**
* 3、add or 简化写法
*/
predicate = x -> x > 5 && x < 9;
//输出 false
System.out.println(predicate.test(10));
//输出 true
System.out.println(predicate.test(6));
}
练习题
/**
* 请在测试类main方法中完成以下需求
* 已知有Integer[] arr = {-12345, 9999, 520, 0,-38,-7758520,941213}
* a) 使用lambda表达式创建Predicate对象p1,p1能判断整数是否是自然数(大于等于0)
* b) 使用lambda表达式创建Predicate对象p2,p2能判断整数的绝对值是否大于100
* c) 使用lambda表达式创建Predicate对象p3,p3能判断整数是否是偶数
* <p>
* 遍历arr,仅利用已创建的Predicate对象(不使用任何逻辑运算符),完成以下需求
* i. 打印自然数的个数
* ii. 打印负整数的个数
* iii. 打印绝对值大于100的偶数的个数
* iv. 打印是负整数或偶数的数的个数
*/
@Test
public void predicate4() {
Predicate<Integer> p1 = x -> x >= 0;
Predicate<Integer> p2 = x -> Math.abs(x) > 100;
Predicate<Integer> p3 = x -> x % 2 == 0;
Integer[] arr = {-12345, 9999, 520, 0, -38, -7758520, 941213};
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
for (Integer item : arr) {
//统计自然数个数
if (p1.test(item)){
count1++;
}
//统计负整数个数
if (p1.negate().test(item)){
count2++;
}
//统计绝对值大于100的偶数个数
if (p2.and(p3).test(item)){
count3++;
}
//统计是负整数或偶数的数的个数
if (p1.negate().or(p3).test(item)){
count4++;
}
}
//分别打印结果
System.out.println("自然数的个数为:"+count1);
System.out.println("负整数的个数为:"+count2);
System.out.println("绝对值大于100的偶数的个数为:"+count3);
System.out.println("是负整数或偶数的数的个数为:"+count4);
}