Java Stream 如何排序

你有没有过整理手机相册的经历?几百张照片混在一起,按拍摄时间、地点或者照片大小排个序,找起来就方便多了。写代码也是一样,当你需要对一组数据(比如员工列表、商品信息)按某个规则重新排列时,Java 8 带来的 Stream 流工具,就能帮你轻松搞定排序这件事,而且比老办法简单得多。

先搞懂基础:Stream 排序的核心逻辑

Stream 排序的本质,就是把你给的“排序规则”,交给流自动处理。举个生活化的例子:你在超市挑苹果,要按价格从低到高摆,你得先告诉收银员“按价格排”,收银员就会把贵的放后面、便宜的放前面。Stream 排序也是这个道理,你只要说清楚“按哪个字段排”“是升序还是降序”,它就会帮你把数据整理好。

Java Stream 如何排序

和之前用循环写排序的老方法比,Stream 不用手动写“如果 A 比 B 大就交换位置”这种重复代码,相当于把排序的“体力活”交给了工具,你只需要负责说清“排序要求”就行,代码更短、更不容易出错。

两种常用排序:简单字段 vs 复杂规则

Stream 排序主要分两种情况,对应你平时会遇到的不同需求,用例子说就很清楚。

第一种是对单个字段排序,比如按年龄、价格这种单一标准。假设你有个员工列表,要按年龄从小到大排,代码怎么写?

你可以这么做:先把列表转成 Stream,然后用 sorted() 方法,告诉它按“员工的年龄”排,最后把排序后的结果转回列表。就像你按价格挑苹果,直接说“按价格”,不用额外要求。

如果要反过来,按年龄从大到小排,只要加个 reversed() 就行,相当于你说“按价格降序”,把之前的顺序反过来。这两种都是最常用的,处理单一规则的需求完全够用。

第二种是对多个字段排序,这也是实际工作中最常见的,比如员工年龄一样时,再按姓名拼音排序。还是用员工的例子,假设两个员工都是25岁,你总不能随便放,得按姓名再排一次。

Stream 可以用 thenComparing() 来接第二个排序规则,就像你买完苹果再挑橘子,先看苹果价格,再看橘子大小。代码里就是先按年龄排,年龄相同的,再按姓名排序,相当于“优先按年龄,其次按姓名”,完美解决多条件排序的问题。

避坑提醒:这些细节要注意

虽然 Stream 排序很简单,但有两个小细节容易踩坑,得提前说清楚。

第一个是空值问题。如果你的数据里有 null,比如某个员工没填年龄,直接排序就会报错,就像你挑苹果时遇到没标价格的,没法判断放哪。这时候可以用 Comparator.nullsFirst() 或 nullsLast(),告诉 Stream 把空值放最前面或者最后面,就像把没标价格的苹果统一放一堆,不影响其他苹果的排序。

第二个是排序规则的类型。如果是字符串(比如姓名),Stream 默认按字母顺序排,比如“张三”会在“李四”前面,符合生活习惯,但如果是数字类型,就别搞混,比如价格的数字,别写成字符串的“10”比“2”小,那肯定不对,得用对应类型的比较规则。

最后再说一句,Stream 排序不是什么高大上的技术,就是把你平时整理东西的逻辑,用代码实现而已。从按时间排相册,到按价格排商品,再到按多条件排员工,生活里的排序需求,Stream 都能搞定,多试几次你就会发现,它比老方法省心太多。

上一篇 C / C++ 编程语言核心特性与应用场景的知识科普