Java 8 Predicate花样用法

Java 8 Predicate花样用法1 简介本文介绍 Java8Predica 链 2 基本用法怎么使用简单的 Predicate 来过滤 list 中的 name Testpublicvo thenSuccess List String names Arrays asList Adam Alexander John Tom String

1. 简介

本文介绍Java 8 Predicate链.

2. 基本用法

怎么使用简单的Predicate来过滤list中的name

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

我们使用Predicate来筛选以大写字母A开头的姓名。

name -> name.startsWith("A")

Java 8 Predicate花样用法

那么如果多个条件这么办?

3. 多条件过滤

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

用两个filter传入两个 Predicate分别过滤  【以A开头的】和【姓名长度小于5】的。

Java 8 Predicate花样用法

Java 8 Predicate花样用法

4. 复杂条件

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

使用一个 filter 传入复杂的Predicate.

Java 8 Predicate花样用法

5. 组合使用Predicate

Predicates可以将 Predicate.and(), Predicate.or() 和 Predicate.negate()组合起来使用。

5.1. Predicate.and()

@Test public void whenFilterListWithCombinedPredicatesUsingAnd_thenSuccess(){ Predicate 
  
    predicate1 = str -> str.startsWith("A"); Predicate 
   
     predicate2 = str -> str.length() < 5; List 
    
      result = names.stream() .filter(predicate1.and(predicate2)) .collect(Collectors.toList()); assertEquals(1, result.size()); assertThat(result, contains("Adam")); } 
     
    
  

两个条件都要满足

Java 8 Predicate花样用法

5.2. Predicate.or()

满足其中一个即可

@Test public void whenFilterListWithCombinedPredicatesUsingOr_thenSuccess(){ Predicate 
  
    predicate1 = str -> str.startsWith("J"); Predicate 
   
     predicate2 = str -> str.length() < 4; List 
    
      result = names.stream() .filter(predicate1.or(predicate2)) .collect(Collectors.toList()); assertEquals(2, result.size()); assertThat(result, contains("John","Tom")); } 
     
    
  

Java 8 Predicate花样用法

5.3. Predicate.negate()

将此条件取反

Predicate

predicate2 =  str -> str.length() < 4;

相当于

Predicate

predicate2 =  str -> str.length() >= 4;

@Test public void whenFilterListWithCombinedPredicatesUsingOrAndNegate_thenSuccess(){ Predicate 
  
    predicate1 = str -> str.startsWith("J"); Predicate 
   
     predicate2 = str -> str.length() < 4; List 
    
      result = names.stream() .filter(predicate1.or(predicate2.negate())) .collect(Collectors.toList()); assertEquals(3, result.size()); assertThat(result, contains("Adam","Alexander","John")); } 
     
    
  

Java 8 Predicate花样用法

5.4. 内联的方式组合使用Predicates

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

6. 组合Predicates集合

在开始介绍之前,简单介绍下  reduce 函数:

 `java.util.stream.Stream#reduce(T, java.util.function.BinaryOperator

)`

源码的注释中给出等价的写法:

 T result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;

即,第一个参数当做初始值,后续参数和第一个参数进行运算,最终得到结果。

接下来我们看下面 reduce 中 and 操作的例子:

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

注意这里初始条件是 true (如果初始条件为 false ,后续即使都满足,和初始值一起 and ,也没结果)

Java 8 Predicate花样用法

然后看 reduce 中使用 or 操作的例子:

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

Java 8 Predicate花样用法

Predicate::or 操作,通常会将初始值设置为 false,因为如果初始值为 true 不管后续条件是否为 true 最终结果都为 true。

7. 结论

本文介绍Java 8 Predicate。介绍了 Predicate在Stream的filter函数中的运用。讲述了复杂的Predicate或者Predicate的组合的用法。

英文原文:https://www.baeldung.com/java-predicate-chain

如果觉得本文对你有帮助,欢迎点赞评论,欢迎关注我,我将努力创作更多更好的文章。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203395.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午9:54
下一篇 2026年3月19日 下午9:54


相关推荐

  • C中结构体和类的区别

    C中结构体和类的区别结构体和类同样能够定义字段 方法和构造函数 都能实例化对象 这样看来结构体和类的功能好像是一样的了 但是他们在数据的存储上是不一样的 C 结构体和类的区别问题这两种数据类型的本质区别主要是各自指向的内存位置不同 传递类的时候 主要表现为是否同时改变了源对象 1 结构体是值类型 类是引用类型虽然结构体的初始化也使用了 new 操作符 可是结构体对象依然分配在堆栈上而不是堆上

    2025年9月4日
    6
  • c++ priority queue_priority

    c++ priority queue_priority既然是队列那么先要包含头文件#include&lt;queue&gt;优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的定义:priority_queue&lt;Type,Container,Functional&gt;Type就是数据类型,Container就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用

    2025年8月24日
    10
  • unit8或double灰度图像的伪彩色显示[通俗易懂]

    unit8或double灰度图像的伪彩色显示[通俗易懂]简单将unit8或double类型灰度图以设定的伪彩色图像显示:  figure,imshow(gray,’Colormap’,jet(255));将灰度图像直接转化为RGB图形:rgb=ind2rgb(gray2ind(im,255),jet(255));如果是unit8数据而不是double类型数据可采用如下伪彩色转换:rgb=label2rgb(gray2ind(…

    2025年12月2日
    6
  • window git安装步骤_Ubuntu git安装

    window git安装步骤_Ubuntu git安装Windows下安装git超详细图文教程

    2025年10月7日
    6
  • IndexReader已解决的问题

    IndexReader已解决的问题

    2022年1月5日
    42
  • linux将时间戳转换为时间_shell脚本获取时间戳

    linux将时间戳转换为时间_shell脚本获取时间戳虽然电脑已经很普遍了,但是一些年长的人对电脑的操作不是很熟悉,比如在使用win7系统时一旦遇到linux时间戳转换时就懵了,对于linux时间戳转换处理起来相对来说较简单,按照我们的步骤处理linux时间戳转换很容易上手,linux时间戳转换具体处理方法如下:Unix时间戳转换怎样在Excel批量修改答:Linux的时间戳其实就是从1970年1月1日0时0分0秒开始到对应时间的秒数,转换可以在当前…

    2022年10月2日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号