目录
Predicate接口的作用
Predicate接口:判断相等isEqual
Predicate接口:评估字符串
Predicate接口:评估Collection集合
Predicate接口:与或非逻辑判断
情景1:过滤掉成绩为空,或者姓名为空、或者id为空的学生
情景2:过滤掉成绩为空,且姓名为空、且id为空的学生
情景3:获取成绩为空,或者姓名为空、或者id为空的学生
Predicate接口的作用
Java 8引入了Predicate函数式接口,主要用于表示一个参数的谓词(布尔值函数),在功能上类似于JavaScript-Array的filter()方法。
关于“谓词”解释,百度给出了如下解释:
此处,Predicate接口主要是:结合自身的default默认方法——与and()、或or()、非negate(),static静态方法isEqual(),返回一个Predicate对象;然后通过重写内部的test()抽象方法,返回一个布尔值。
这个布尔值就可以用于表示被描述的对象是否与指定的条件相符合(true),或者不符合(false)。
Predicate接口:判断相等isEqual
Predicate接口提供了静态成员方法isEqual(),用于判断两个对象是否相等。一个经典应用场景是:结合Stream流式操作,根据指定元素的值,筛选集合中与之相同的所有元素、计算集合中与之相同的元素个数。
例如:我们想筛选集合Collection<TStudent>中,与给定元素相等的元素及其个数,示例代码如下,
PS:注意TStudent类需要重写equals和hasCode()方法。
public static void main(String[] args) {
Collection<TStudent> collection1 = new ArrayList<>();
collection1.add(new TStudent(1, "Tom", 3.8));
collection1.add(new TStudent(2, null, 3.5));
collection1.add(new TStudent(3, "John", 2.3));
collection1.add(new TStudent(4, "Mike", null));
collection1.add(new TStudent(null, "Yoke", 4.5));
collection1.add(new TStudent(2, null, 3.5));
collection1.add(new TStudent());
System.out.println("原始集合:");
collection1.forEach(System.out::println);
TStudent temp = new TStudent(2, null, 3.5);
Predicate<TStudent> predicate = Predicate.isEqual(temp);
System.out.println("【筛选统计结果】");
//1-获取集合中等于temp的元素
Stream<TStudent> tStudentStream = collection1.stream().filter(predicate);
List<TStudent> collect = tStudentStream.collect(Collectors.toList());//Stream转List
collect.forEach(System.out::println);
//2-统计集合中等于temp的元素个数
long count = collection1.stream().filter(predicate).count();
System.out.println("个数:"+count);
}
Predicate接口:评估字符串
Predicate<T>接口可以接收一个泛型类型,此处,我们可以接收一个String字符串,借助一个Predicate接口实例,来评估字符串是否满足指定规则。
定义规则为:字符串的长度大于5,且包含任意英文字母时,即为通过测试。
示例代码如下,
//methods
public static void main(String[] args) {
//利用Predicate接口判断String字符串是否满足指定规则
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
//判断:[1]长度是否大于5;[2]是否包含英文字母
return s.length()>5&&s.matches(".*[a-zA-Z].*");
}
};
boolean test1 = predicate.test("123a45");
System.out.println(test1);
boolean test2 = predicate.test("659748");
System.out.println(test2);
}
Predicate接口:评估Collection集合
Predicate<T>接口也可以与Collection集合对象结合,用于实现集合元素的过滤操作。
例如,指定规则为:删除Collection<Integer>集合对象中所有的奇数。示例代码如下,
public static void main(String[] args) {
//定义集合对象
Collection collection = new ArrayList();
collection.add(1);
collection.add(2);
collection.add(3);
collection.add(4);
collection.add(5);
boolean flag = collection.removeIf(new Predicate() {
@Override
public boolean test(Object o) {
Integer value = Integer.parseInt(o.toString());
return value % 2 != 0;
}
});
System.out.println("flag="+flag);
collection.forEach(System.out::println);
}
更复杂一点的应用场景,我们可以借助Predicate<Student>来过滤掉绩点成绩为空的学生元素。示例代码如下,
//methods
public static void main(String[] args) {
//定义集合对象
Collection<TStudent> collection1 = new ArrayList<>();
collection1.add(new TStudent(1,"Tom",null));
collection1.add(new TStudent(2,"Linda",null));
collection1.add(new TStudent(3,"John",2.3));
collection1.add(new TStudent(4,"Mike",null));
collection1.add(new TStudent(5,"Yoke",4.5));
//Predicate<TStudent>过滤掉绩点成绩为空的学生元素
boolean flag1 = collection1.removeIf(new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
}
});
System.out.println("flag1="+flag1);
collection1.forEach(System.out::println);
}
Predicate接口:与或非逻辑判断
以上示例仅仅是使用了Predicate接口的test()方法。
Predicate接口也提供了三个默认方法and()、or()、negate(),用于执行与或非逻辑判断,但是如何使用呢?
以下,我们创建三个Predicate对象,分别用于判断:
【1】Predicate-1:判断学生成绩是否为空;
【2】Predicate-2:判断学生姓名是否为空;
【3】Predicate-3:判断学生的Id是否为空。
然后我们执行以下几类操作,
【1】过滤掉成绩为空,或者姓名为空、或者id为空的学生;
【2】过滤掉成绩为空,且姓名为空、且id为空的学生;
【3】获取成绩为空,或者姓名为空、或者id为空的学生;
示例代码如下,
情景1:过滤掉成绩为空,或者姓名为空、或者id为空的学生
public static void main(String[] args) {
Collection<TStudent> collection1 = new ArrayList<>();
collection1.add(new TStudent(1, "Tom", 3.8));
collection1.add(new TStudent(2, null, 3.5));
collection1.add(new TStudent(3, "John", 2.3));
collection1.add(new TStudent(4, "Mike", null));
collection1.add(new TStudent(null, "Yoke", 4.5));
System.out.println("过滤前:");
collection1.forEach(System.out::println);
//Predicate-判断学生id为空
Predicate<TStudent> predicate_id = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent)||Objects.isNull(tStudent.getId());
}
};
//Predicate-判断学生姓名为空
Predicate<TStudent> predicate_name = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent)||Objects.isNull(tStudent.getName());
}
};
//Predicate-判断学生成绩为空
Predicate<TStudent> predicate_grade = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
}
};
System.out.println("过滤后:");
//[1] 过滤掉成绩为空,或者姓名为空、或者id为空的学生;
boolean flag_1 = collection1.removeIf(predicate_id.or(predicate_name).or(predicate_grade));
collection1.forEach(System.out::println);
}
情景2:过滤掉成绩为空,且姓名为空、且id为空的学生
public static void main(String[] args) {
Collection<TStudent> collection1 = new ArrayList<>();
collection1.add(new TStudent(1, "Tom", 3.8));
collection1.add(new TStudent(2, null, 3.5));
collection1.add(new TStudent(3, "John", 2.3));
collection1.add(new TStudent(4, "Mike", null));
collection1.add(new TStudent(null, "Yoke", 4.5));
collection1.add(new TStudent());
System.out.println("过滤前:");
collection1.forEach(System.out::println);
//Predicate-判断学生id为空
Predicate<TStudent> predicate_id = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent)||Objects.isNull(tStudent.getId());
}
};
//Predicate-判断学生姓名为空
Predicate<TStudent> predicate_name = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent)||Objects.isNull(tStudent.getName());
}
};
//Predicate-判断学生成绩为空
Predicate<TStudent> predicate_grade = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
}
};
System.out.println("过滤后:");
//[2] 过滤掉成绩为空,且姓名为空、且id为空的学生
boolean flag_2 = collection1.removeIf(predicate_id.and(predicate_name).and(predicate_grade));
collection1.forEach(System.out::println);
}
情景3:获取成绩为空,或者姓名为空、或者id为空的学生
public static void main(String[] args) {
Collection<TStudent> collection1 = new ArrayList<>();
collection1.add(new TStudent(1, "Tom", 3.8));
collection1.add(new TStudent(2, null, 3.5));
collection1.add(new TStudent(3, "John", 2.3));
collection1.add(new TStudent(4, "Mike", null));
collection1.add(new TStudent(null, "Yoke", 4.5));
collection1.add(new TStudent());
System.out.println("过滤前:");
collection1.forEach(System.out::println);
//Predicate-判断学生id为空
Predicate<TStudent> predicate_id = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent)||Objects.isNull(tStudent.getId());
}
};
//Predicate-判断学生姓名为空
Predicate<TStudent> predicate_name = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent)||Objects.isNull(tStudent.getName());
}
};
//Predicate-判断学生成绩为空
Predicate<TStudent> predicate_grade = new Predicate<TStudent>() {
@Override
public boolean test(TStudent tStudent) {
return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
}
};
System.out.println("过滤后:");
//[3] 获取成绩为空,或者姓名为空、或者id为空的学生-[即:过滤掉ID、name、grade都不为空的元素]
boolean flag_3 = collection1.removeIf(predicate_id.negate().and(predicate_name.negate()).and(predicate_grade.negate()));
collection1.forEach(System.out::println);
}