java.util.function中 Function, Supplier, Consumer, Predicate和其他函數(shù)式接口廣泛用在支持lambda表達(dá)式的API中。這些接口有一個(gè)抽象方法,會(huì)被lambda表達(dá)式的定義所覆蓋。
@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接口主要用來(lái)判斷一個(gè)參數(shù)是否符合要求,類似于Junit的assert.
其核心方法如下:
-
boolean test(T t);
用來(lái)處理參數(shù)T,看起是否滿足要求,可以理解為 條件A -
default Predicate<T> and(Predicate<? super T> other),可理解為 條件A && 條件B
調(diào)用當(dāng)前Predicate的test方法之后再去調(diào)用other的test方法,相當(dāng)于進(jìn)行兩次判斷
-
default Predicate<T> negate()
對(duì)當(dāng)前判斷進(jìn)行"!"操作,即取非操作,可理解為 ! 條件A
-
default Predicate<T> or(Predicate<? super T> other)
對(duì)當(dāng)前判斷進(jìn)行"||"操作,即取或操作,可以理解為 條件A ||條件B
-
static <T> Predicate<T> isEqual(Object targetRef)
對(duì)當(dāng)前操作進(jìn)行"="操作,即取等操作,可以理解為 A == B
下面對(duì)上述方法進(jìn)行實(shí)例測(cè)試:
test(T t)
判斷給定的值是否大于0
Predicate<Integer> predicate = x -> x > 0;
System.out.println(predicate.test(100));
結(jié)果為:
true
and(Predicate<? super T> other)
判斷給定的值是否是大于100的偶數(shù)
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));
結(jié)果為:
false
true
false
negate()
計(jì)算一批用戶中年齡大于22歲的用戶的數(shù)量
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;
}
}
測(cè)試代碼:
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()
);
結(jié)果為:
4
or(Predicate<? super T> other)
計(jì)算一批用戶中名稱為"lisi"或者年齡大于25歲的用戶的數(shù)量
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)
假設(shè)認(rèn)為兩個(gè)用戶如果年齡一樣,名字一樣,我們認(rèn)為是一樣的,那我們來(lái)找下給定的一批用戶中一樣的用戶
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;
}
}
測(cè)試代碼:
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()
);
結(jié)果為:
2
與Predicate<T>相關(guān)的接口
-
BiPredicate<T, U>
針對(duì)兩個(gè)參數(shù),看兩個(gè)參數(shù)是否符合某個(gè)條件表達(dá)式
-
DoublePredicate
看一個(gè)double類型的值是否符合某個(gè)條件表達(dá)式
-
IntPredicate
看一個(gè)int類型的值是否符合某個(gè)條件表達(dá)式
-
LongPredicate
看一個(gè)long類型的值是否符合某個(gè)條件表達(dá)式