在接下来的阶段中,将和你们分享Java 8 系列的一些知识点。本文和你们讲述Predicate的使用方法介绍以及其背景。bash
首先,让咱们看看如何使用简单的filter()
来过滤一个List集合:spa
@Test
public void whenFilterList(){
List<String> names = Arrays.asList("Apps", "Alibaba", "william", "Son");
List<String> result = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertThat(result, contains("Apps","Alibaba"));
}
复制代码
在此示例中,咱们过滤了List集合,保留以“A”开头的数据 :code
name -> name.startsWith("A")
复制代码
可是假如须要过滤多个条件的话,应该如何?cdn
若是咱们想要应用多个过滤,一个比较简单地方式就是设置多个过滤器:blog
@Test
public void whenFilterListWithMultiple(){
List<String> result = names.stream()
.filter(name -> name.startsWith("A"))
.filter(name -> name.length() < 5)
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Apps"));
}
复制代码
看上面的示例,经过提取以“A”开头而且长度小于5的数据来过滤咱们的集合。ip
咱们使用了两个过滤条件。string
如今,咱们能够使用一个带有复杂的过滤器,而不是使用多个过滤器filer()
:it
@Test
public void whenFilterListWithComplexPredicate(){
List<String> result = names.stream()
.filter(name -> name.startsWith("A") && name.length() < 5)
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Adam"));
}
复制代码
这个改进比第一个更灵活,由于咱们能够使用按位运算来构建咱们想要的复杂语句。io
接下来,若是咱们不想使用按位运算构建复杂语句,Java 8 Predicate能够使用有用的方法来组合过滤条件。function
咱们将使用Predicate.and()
,Predicate.or()
和Predicate.negate()
方法组合Predicates。
咱们来看看只用 and()
的方式,能够怎么用
@Test
public void whenFilterListWithCombinedPredicatesUsingAnd(){
Predicate<String> predicate1 = str -> str.startsWith("A");
Predicate<String> predicate2 = str -> str.length() < 5;
List<String> result = names.stream()
.filter(predicate1.and(predicate2))
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Adam"));
}
复制代码
这样的语法很是直观,方法名称代表了操做的类型。使用and()
,咱们经过仅提取知足两个条件的名称来过滤咱们的List。
接下来,咱们看看or()
的方式使用。条件为w开头
、或者长度小于4
;
@Test
public void whenFilterListWithCombinedPredicatesUsingOr(){
Predicate<String> predicate1 = str -> str.startsWith("w");
Predicate<String> predicate2 = str -> str.length() < 4;
List<String> result = names.stream()
.filter(predicate1.or(predicate2))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertThat(result, contains("John","Tom"));
}
复制代码
如今咱们来结合一下看看 negate()
的使用场景,这个方法是指相反条件,即 <>
,!xxx
。
@Test
public void whenFilterListWithCombinedPredicatesUsingOrAndNegate(){
Predicate<String> predicate1 = str -> str.startsWith("w");
Predicate<String> predicate2 = str -> str.length() < 4;
List<String> result = names.stream()
.filter(predicate1.or(predicate2.negate()))
.collect(Collectors.toList());
assertEquals(3, result.size());
assertThat(result, contains("Apps","Alibaba","william"));
}
复制代码
上示例的代码中,条件是为 w开头的或者 数据的长度不是小于4的过滤条件。
咱们甚至也能够不用写 and()、or()、negate()就能够使用predicate方法:
@Test
public void whenFilterListWithCombinedPredicatesInline(){
List<String> result = names.stream()
.filter(((Predicate<String>)name -> name.startsWith("A"))
.and(name -> name.length()<5))
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Apps"));
}
复制代码
最后,让咱们看看如何经过编写出一个能够支持多个复杂条件的过滤方法。
在下面的例子中,咱们有一个列表集合,咱们使用组合Predicate.and() :
@Test
public void whenFilterListWithCollectionOfPredicatesUsingAnd(){
List<Predicate<String>> allPredicates = new ArrayList<Predicate<String>>();
allPredicates.add(str -> str.startsWith("A"));
allPredicates.add(str -> str.contains("ba"));
allPredicates.add(str -> str.length() > 4);
List<String> result = names.stream()
.filter(allPredicates.stream().reduce(x->true, Predicate::and))
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Alibaba"));
}
复制代码
请留意,咱们使用了一个关键性代码:
x->true
复制代码
可是若是咱们想要使用Predicate.or()
组合它们会有所不一样:
@Test
public void whenFilterListWithCollectionOfPredicatesUsingOr(){
List<String> result = names.stream()
.filter(allPredicates.stream().reduce(x->false, Predicate::or))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertThat(result, contains("Apps","Alibaba"));
}
复制代码
本文主要是讲解了如何更好的过滤List中的数据,filter()
、Predicates
的使用方法,已经针对的场景。