java.util.function中 Function, Supplier, Consumer, Predicate和其他函数式接口广泛用在支持lambda表达式的API中。这些接口有一个抽象方法,会被lambda表达式的定义所覆盖。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
Predicate接口主要用来判断一个参数是否符合要求,类似于Junit的assert.
其核心方法如下:
-
boolean test(T t);
用来处理参数T,看起是否满足要求,可以理解为 条件A
-
default Predicate<T> and(Predicate<? super T> other),可理解为 条件A && 条件B
调用当前Predicate的test方法之后再去调用other的test方法,相当于进行两次判断
-
default Predicate<T> negate()
对当前判断进行"!"操作,即取非操作,可理解为 ! 条件A
-
default Predicate<T> or(Predicate<? super T> other)
对当前判断进行"||"操作,即取或操作,可以理解为 条件A ||条件B
-
static <T> Predicate<T> isEqual(Object targetRef)
对当前操作进行"="操作,即取等操作,可以理解为 A == B
下面对上述方法进行实例测试:
test(T t)
判断给定的值是否大于0
Predicate<Integer> predicate = x -> x > 0;
System.out.println(predicate.test(100));
结果为:
true
and(Predicate<? super T> other)
判断给定的值是否是大于100的偶数
Predicate<Integer> predicate = x -> x >100;
predicate = predicate.and(x -> x % 2 == 0 );
System.out.println(predicate.test(98));
System.out.println(predicate.test(102));
System.out.println(predicate.test(103));
结果为:
false
true
false
negate()
计算一批用户中年龄大于22岁的用户的数量
Person类:
class Person{
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试代码:
Predicate<Person> personPredicate = x -> x.age > 22;
System.out.println(
Stream.of(
new Person(21,"zhangsan"),
new Person(22,"lisi"),
new Person(23,"wangwu"),
new Person(24,"wangwu"),
new Person(25,"lisi"),
new Person(26,"zhangsan")
)
.filter(personPredicate.negate())
.count()
);
结果为:
4
or(Predicate<? super T> other)
计算一批用户中名称为"lisi"或者年龄大于25岁的用户的数量
Predicate<Person> predicate = x -> x.name.equals("lisi");
predicate = predicate.or(x -> x.age > 25);
System.out.println(
Stream.of(
new Person(21,"zhangsan"),
new Person(22,"lisi"),
new Person(23,"wangwu"),
new Person(24,"wangwu"),
new Person(25,"lisi"),
new Person(26,"zhangsan")
)
.filter(predicate)
.count()
);
isEqual(Object targetRef)
假设认为两个用户如果年龄一样,名字一样,我们认为是一样的,那我们来找下给定的一批用户中一样的用户
Person类:
class Person{
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age ||!name.equals(person.name)) return false;
return true;
}
@Override
public int hashCode() {
int result = age;
result = 31 * result + name.hashCode();
return result;
}
}
测试代码:
Person person = new Person(22,"lisi");
Predicate<Person> predicate = Predicate.isEqual(person);
System.out.println(
Stream.of(
new Person(21,"zhangsan"),
new Person(22,"lisi"),
new Person(23,"wangwu"),
new Person(24,"wangwu"),
new Person(22,"lisi"),
new Person(26,"zhangsan")
)
.filter(predicate)
.count()
);
结果为:
2
与Predicate<T>相关的接口
-
BiPredicate<T, U>
针对两个参数,看两个参数是否符合某个条件表达式
-
DoublePredicate
看一个double类型的值是否符合某个条件表达式
-
IntPredicate
看一个int类型的值是否符合某个条件表达式
-
LongPredicate
看一个long类型的值是否符合某个条件表达式