java中lambda配合stream可简洁实现多重过滤与多条件排序:过滤用单个predicate合并条件并注意null安全,排序用comparator.comparing链式构建并处理null及倒序。

Java 中 Lambda 表达式配合 Stream API,能用简洁、可读性强的方式实现多重过滤与多条件排序,核心在于 filter() 链式组合 + Comparator 的级联构建。
多重过滤:多个条件叠加判断
不是写多个 filter() 套娃,而是把逻辑合并进一个 Predicate —— 更高效,也避免重复遍历。
- 用 &&(且) 连接多个条件,比如:年龄在 18–60 之间且状态为激活
- 用 ||(或) 表达任一满足即可,例如:部门是“研发”或“测试”
- 注意 null 安全:若字段可能为空,先用
Objects.nonNull()判断,再调用方法
示例:
List<user> result = users.stream()
.filter(u -> Objects.nonNull(u)
&& u.getAge() >= 18
&& u.getAge()
<h3>多条件排序:按优先级逐层定义</h3>
<p>使用 <code>Comparator.comparing()</code> 构建主序,再用 <code>thenComparing()</code> 追加次序;支持正序、倒序混搭。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24"><img
src="https://img.php.cn/upload/manual/001/431/639/6ad0919a12f37751.png" alt="OpenJDK 24" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24" class="overflowclass">OpenJDK 24</a>
<p class="overflowclass"></p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>先按部门名称升序,再按入职时间降序: <code>comparing(User::getDept).thenComparing(User::getHireDate, Comparator.reverseOrder())</code>
</li>
<li>字段可能为 null?用 <code>Comparator.nullsLast()</code> 或 <code>nullsFirst()</code> 显式处理</li>
<li>若需倒序整个排序链,最后加 <code>.reversed()</code>;但更推荐在每个字段上单独控制方向</li>
</ul>
<p>示例:</p>
<pre class="brush:java;toolbar:false;">List<user> sorted = users.stream()
.sorted(Comparator.comparing(User::getDept)
.thenComparing(User::getSalary, Comparator.reverseOrder())
.thenComparing(User::getId))
.collect(Collectors.toList());</user>
过滤 + 排序组合:流式一气呵成
Stream 天然支持链式调用,过滤和排序可以无缝衔接,中间不生成临时集合,JVM 还可能做优化。
- 顺序不能颠倒:必须先
filter()再sorted(),否则无效排序会浪费资源 - 数据库关联查询慎用:如
xMapper.selectLimitTimes(x.getId())在 filter 中调用,属于 N+1 查询,应提前预加载到内存再处理 - 如需稳定顺序(比如分页),建议加上
thenComparing主键,避免同值时结果不稳定
典型写法:
List<x> filteredAndSorted = xList.stream()
.filter(x -> x.getLimitTimes() > xMapper.selectLimitTimes(x.getId()))
.sorted(Comparator.comparing(X::getLimitTimes)
.thenComparing(X::getId))
.collect(Collectors.toList());</x>
常见陷阱与规避建议
写得顺手容易忽略底层行为,几个关键点要留心:
-
filter()和sorted()都是中间操作,不触发执行;collect()才真正运算 - 别在
filter或forEach里修改外部变量或打印日志——副作用会破坏函数式语义,尤其并行流下不可控 - 小列表(
- 空集合、null 元素不会自动跳过,务必显式防护,否则运行时报
NullPointerException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










