这是一个非常典型的 Java Stream 流 排序操作,通常用于对集合中的对象(在这里是 prizeDTO)按照其内部嵌套属性(tiers 对象的 code 属性)进行排序。
这段代码结合了 Lambda 表达式 和 函数式接口 的特性。为了让你更清晰地理解,我将其拆解开来详细解释:

🔍 代码逐层解析

这段代码主要由两部分组成:.stream() 和 .sorted(…)。

1. .stream()

作用:这是流的入口。
功能:将一个集合(如 List)转换为一个 Stream。只有转换成流之后,你才能使用 .sorted()、.filter() 等一系列强大的流式操作 API。

2. .sorted(Comparator.comparingInt(…))

这是排序的核心逻辑,我们再把它细分为三层来看:

.sorted(…) (最外层)

定义:Stream API 的一个中间操作。
作用:对流中的元素进行排序。
特性:它是惰性的。这意味着如果你只写了这行代码,排序并不会立即执行。只有当你后续调用了终端操作(如 .collect() 收集结果或 .forEach() 遍历)时,排序才会真正发生。

Comparator.comparingInt(…) (中层)

定义:Comparator 接口提供的一个静态工厂方法。
作用:生成一个用于比较整数的比较器。
优势:它专门用于处理 int 基本类型。相比于通用的 comparing() 方法,comparingInt() 能够避免 int 和 Integer 之间的自动装箱/拆箱操作,在处理大量数据时性能更优。

prizeDTO -> prizeDTO.getTiers().getCode() (最内层 - Lambda 表达式)

定义:一个函数式接口的实现。
逻辑拆解:
prizeDTO:代表流中的每一个元素(即集合里的每一个奖品对象)。
getTiers():调用该对象的 getTiers() 方法,获取其内部的“层级”对象(Tier)。
getCode():再调用“层级”对象的 getCode() 方法,获取具体的代码值(通常是一个 int 类型的排序权重或编号)。
核心含义:它告诉程序“根据什么来比”。在这里,就是告诉程序:“提取出 prizeDTO 里 tiers 的 code 值,拿这个值去跟别的元素比”。

📝 翻译成“人话”

如果这行代码在你的项目中,它的实际含义是:
“请把这个列表里的所有奖品(prizeDTO),按照它们所属层级(tiers)的代码编号(code)进行升序排列(从小到大)。”

⚙️ 它是如何工作的?

提取键值:对于集合中的每一个 prizeDTO 对象,系统都会执行 prizeDTO.getTiers().getCode() 这段代码,拿到一个整数(例如:1, 3, 2)。
比较大小:comparingInt 会根据这些提取出来的整数进行比较。
重新排序:根据比较结果,调整流中元素的顺序。

💡 常见的变体与扩展

在实际开发中,你可能会遇到或需要修改为以下几种情况:

需求场景 代码写法 说明
降序排列 .sorted(Comparator.comparingInt(prizeDTO -> prizeDTO.getTiers().getCode()).reversed()) 在末尾加上 .reversed() 即可实现从大到小排序。
处理空值 Comparator.nullsFirst(...) 包裹 如果 getTiers() 可能返回 null,直接运行会报错。需要使用 nullsFirst 或先用 filter 过滤掉空值。
多级排序 .thenComparing(...) 如果 code 相同,可以链式调用 thenComparing 指定第二排序条件。
简化写法 静态导入 comparingInt 如果在文件头部静态导入了 java.util.Comparator.*,可以省略前面的 Comparator.

⚠️ 注意事项

空指针异常(NPE):这段代码隐含了一个风险。如果某个 prizeDTO 的 getTiers() 返回 null,程序会抛出 NullPointerException。如果数据可能为空,建议先进行过滤(.filter(prize -> prize.getTiers() != null))或使用更复杂的 Comparator.nullsFirst() 处理。
不可变性:.sorted() 不会改变原始集合的顺序,它返回的是一个新的有序流。你需要通过 .collect(Collectors.toList()) 来收集结果。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐