comparator 是策略模式的典型落地:它定义“怎么比”的行为契约,由 arrays.sort() 等 context 持有并运行时调用 compare();支持 lambda、链式组合及 spring 条件化装配;但仅负责两对象顺序判定,空值处理等应由外层封装。

Comparator 就是策略模式的典型落地
Java 中 Comparator 接口不是工具类,而是标准的策略接口。它定义了“怎么比”这一行为契约,不关心谁来比、在哪比——真正执行比较逻辑的是你写的实现类或 Lambda 表达式。Arrays.sort()、Collections.sort()、TreeSet 构造等,都把 Comparator 当作 Strategy 对象传入 Context(比如排序方法内部),运行时调用 compare(),完全符合策略模式三要素:Context 持有策略引用、Strategy 定义统一接口、ConcreteStrategy 提供具体实现。
排序逻辑切换靠的是替换 Comparator 实例
不需要改排序代码本身,只要换一个 Comparator,排序规则就变了。这种切换可以发生在任意时刻:
- 按字符串长度排序 → 传入
(s1, s2) -> Integer.compare(s1.length(), s2.length()) - 按价格降序 → 传入
Comparator.comparing(Product::getPrice).reversed() - 多级排序 → 链式组合:
Comparator.comparing(Product::getCategory).thenComparing(Product::getName) - 运行时配置驱动 → 从配置读取字段名,用反射或 Map 查找对应 Comparator Bean
Spring 环境下策略更轻量也更可控
在 Spring 项目中,可以把不同 Comparator 声明为 @Bean,并用 @Qualifier 或条件化装配(@ConditionalOnProperty)控制启用哪一个。例如:
- 定义
@Bean("priceAscComparator")和@Bean("priceDescComparator") - 通过配置项
app.sort.by=price-desc动态注入对应 Bean 到排序服务中 - 配合 FactoryBean 或 StrategyResolver,实现 key→Comparator 的运行时映射
注意边界:Comparator 不等于“所有比较场景”
它专注解决“两个对象谁前谁后”,不处理数据加载、异常兜底、缓存或跨类型转换。如果业务需要根据用户角色返回不同排序结果,或某字段为空时走默认逻辑,这些不属于 Comparator 职责,应由外层 Context(如 Service 方法)预处理或封装一层适配器。强行把空值判断、权限校验塞进 compare(),反而破坏策略的纯粹性和复用性。










