Java 8谓词链

栏目: Java · 发布时间: 7年前

内容简介:在本快速教程中,我们将讨论在Java 8中谓词链Predicates的不同方法。让我们看看如何使用简单的谓词来过滤名称列表:在这个例子中,我们过滤了名称列表,只使用谓词保留以“A”开头的名称  :

在本快速教程中,我们将讨论在 Java 8中谓词链Predicates的不同方法。

让我们看看如何使用简单的谓词来过滤名称列表:

@Test
<b>public</b> <b>void</b> whenFilterList_thenSuccess(){
   List<String> names = Arrays.asList(<font>"Adam"</font><font>, </font><font>"Alexander"</font><font>, </font><font>"John"</font><font>, </font><font>"Tom"</font><font>);
   List<String> result = names.stream()
     .filter(name -> name.startsWith(</font><font>"A"</font><font>))
     .collect(Collectors.toList());
    
   assertEquals(2, result.size());
   assertThat(result, contains(</font><font>"Adam"</font><font>,</font><font>"Alexander"</font><font>));
}
</font>

在这个例子中,我们过滤了名称列表,只使用谓词保留以“A”开头的名称  :

name -> name.startsWith("A")

但是,如果我们想要应用多个谓词呢?

多个过滤器

如果我们想要应用多个谓词,一个选项是简单地链接多个过滤器:

@Test
<b>public</b> <b>void</b> whenFilterListWithMultipleFilters_thenSuccess(){
    List<String> result = names.stream()
      .filter(name -> name.startsWith(<font>"A"</font><font>))
      .filter(name -> name.length() < 5)
      .collect(Collectors.toList());
 
    assertEquals(1, result.size());
    assertThat(result, contains(</font><font>"Adam"</font><font>));
}
</font>

复杂的谓词

我们可以使用一个带有复杂谓词的过滤器,而不是使用多个过滤器:

@Test
<b>public</b> <b>void</b> whenFilterListWithComplexPredicate_thenSuccess(){
    List<String> result = names.stream()
      .filter(name -> name.startsWith(<font>"A"</font><font>) && name.length() < 5)
      .collect(Collectors.toList());
 
    assertEquals(1, result.size());
    assertThat(result, contains(</font><font>"Adam"</font><font>));
}
</font>

这个选项比第一个选项更灵活,因为我们可以使用按位运算来构建我们想要的复杂谓词。

.结合  谓词

如果我们不想使用按位运算构建复杂的谓词,Java 8 Predicate可以使用有用的方法来组合谓词。

我们将使用Predicate.and(),Predicate.or()和Predicate.negate()方法组合谓词。

我们将明确定义我们的谓词,然后我们将使用Predicate.and()组合它们  :

@Test
<b>public</b> <b>void</b> whenFilterListWithCombinedPredicatesUsingAnd_thenSuccess(){
    Predicate<String> predicate1 =  str -> str.startsWith(<font>"A"</font><font>);
    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(</font><font>"Adam"</font><font>));
}
</font>

我们可以看到,语法非常直观,方法名称表明了操作的类型,

我们也可以使用  Predicate.or()来组合Predicates。

让我们提取名称以“J”开头,以及长度小于4的名称:

@Test
<b>public</b> <b>void</b> whenFilterListWithCombinedPredicatesUsingOr_thenSuccess(){
    Predicate<String> predicate1 =  str -> str.startsWith(<font>"J"</font><font>);
    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(</font><font>"John"</font><font>,</font><font>"Tom"</font><font>));
}
</font>

在组合我们的Predicates时我们也可以使用Predicate.negate():

@Test
<b>public</b> <b>void</b> whenFilterListWithCombinedPredicatesUsingOrAndNegate_thenSuccess(){
    Predicate<String> predicate1 =  str -> str.startsWith(<font>"J"</font><font>);
    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(</font><font>"Adam"</font><font>,</font><font>"Alexander"</font><font>,</font><font>"John"</font><font>));
}
</font>

在这里,我们使用or()和negate()的组合来按名称以“J”开头或长度不小于4 来过滤List。

结合谓词内联

我们不需要明确定义 Predicates要使用and(),  or(), 和negate().

可以通过强制Cast谓词来内联它们  :

@Test
<b>public</b> <b>void</b> whenFilterListWithCombinedPredicatesInline_thenSuccess(){
    List<String> result = names.stream()
      .filter(((Predicate<String>)name -> name.startsWith(<font>"A"</font><font>))
      .and(name -> name.length()<5))
      .collect(Collectors.toList());
 
    assertEquals(1, result.size());
    assertThat(result, contains(</font><font>"Adam"</font><font>));
}
</font>

结合一组谓词

最后,让我们看看如何通过Reducing合并它们来链接一组Predicates。

在下面的例子中,我们有一个列表的谓词,我们使用组合Predicate.and():

@Test
<b>public</b> <b>void</b> whenFilterListWithCollectionOfPredicatesUsingAnd_thenSuccess(){
    List<Predicate<String>> allPredicates = <b>new</b> ArrayList<Predicate<String>>();
    allPredicates.add(str -> str.startsWith(<font>"A"</font><font>));
    allPredicates.add(str -> str.contains(</font><font>"d"</font><font>));        
    allPredicates.add(str -> str.length() > 4);
     
    List<String> result = names.stream()
      .filter(allPredicates.stream().reduce(x-><b>true</b>, Predicate::and))
      .collect(Collectors.toList());
     
    assertEquals(1, result.size());
    assertThat(result, contains(</font><font>"Alexander"</font><font>));
}
</font>

请注意:x->true 标识

如果我们想要使用Predicate.or()组合它们会有所不同:

@Test
<b>public</b> <b>void</b> whenFilterListWithCollectionOfPredicatesUsingOr_thenSuccess(){
    List<String> result = names.stream()
      .filter(allPredicates.stream().reduce(x->false, Predicate::or))
      .collect(Collectors.toList());
     
    assertEquals(2, result.size());
    assertThat(result, contains(<font>"Adam"</font><font>,</font><font>"Alexander"</font><font>));
}
</font>

完整的源代码可以 在GitHub上获得


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

《10%创业家》

《10%创业家》

[美] 帕特里克•J.麦金尼斯 / 李文远 / 广东人民出版社 / 2017-4 / 45.00

还在打工和创业之间苦苦挣扎吗?麦金尼斯用亲身经历告诉你,不用辞职,只需投入10%的时间和资源,就能获得100%的财务自由。你不需要雄厚的资本,也不必占用工作时间,只要准确掌握本书所授的方法,就能立即开始创业。 麦金尼斯是世界银行风投顾问,同时也是一名10%创业家。在本书中,他结合自身的创业咨询经历,为读者讲解了移动互联时代的5种创业模式,还提供了创业基因测试、10%创业计划、自传模板等个性化......一起来看看 《《10%创业家》》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具