1 简介
Java 8引入了许多函数式接口Functional Interface,Predicate则是常用的一个。Predicate主要的方法为:
boolean test(T t);
它传入一个对象,并返回一个boolean值,这在stream中用得非常多,本文简单介绍它的基本用法。
2 基本用法
2.1 单一filter中的使用
List<String> names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
List<String> result = names.stream()
.filter(name -> name.contains("m"))
.collect(Collectors.toList());
assertEquals(3, result.size());
assertTrue(result.contains("Jeremy"));
代码中,name -> name.contains("m")
,为Predicate,表示字符串包含m
的才满足条件。
2.2 多个filter中的使用
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(name -> name.startsWith("S"))
.filter(name -> name.contains("m"))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertEquals(asList("Sam", "Simon"), result);
通过filter可以不断连接各种条件判断。
2.3 条件运算符组合使用
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(name -> name.startsWith("S") && name.contains("m"))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertEquals(asList("Sam", "Simon"), result);
通过条件运算符&
、|
和!
等实现与或非。
3 组合用法
3.1 与门and的使用
Predicate<String> startsWith_S = str -> str.startsWith("S");
Predicate<String> contains_m = str -> str.contains("m");
//and
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(startsWith_S.and(contains_m))
.collect(Collectors.toList());
assertEquals(asList("Sam", "Simon"), result);
通过Predicate.and()
方法,把两个条件组合起来,表示需要同时满足两个条件。
3.2 或门or的使用
//or
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(startsWith_S.or(contains_m))
.collect(Collectors.toList());
assertEquals(asList("Jeremy", "Sam", "Simon"), result);
3.3 非门negeate的使用
//negate
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(startsWith_S.negate())
.collect(Collectors.toList());
assertEquals(asList("Larry", "Jeremy", "Mike"), result);
3.4 多个合并使用
//Collection
Predicate<String> length_gt4 = str -> str.length() > 4;
List<Predicate<String>> allPredicates = asList(
startsWith_S,
contains_m,
length_gt4
);
//and
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(allPredicates.stream().reduce(x -> true, Predicate::and))
.collect(Collectors.toList());
assertEquals(singletonList("Simon"), result);
//or
names = asList("Larry", "Jeremy", "Sam", "Simon", "Mike");
result = names.stream()
.filter(allPredicates.stream().reduce(x -> false, Predicate::or))
.collect(Collectors.toList());
assertEquals(asList("Larry", "Jeremy", "Sam", "Simon"), result);
需要注意的是:
与逻辑的时候,开始为x -> true
;
而或逻辑的时候,开始为x -> false
。
总结
Predicate
在Java 8中很常用,特别是在Optional
和Stream
等有filter
时,需要灵活掌握其基本用法。