Java中使用Collator实现对象List按照中文姓名属性进行A-Z的排序实现

场景

Java接口中返回的包含中文姓名属性的实体的List,需要按照A-Z的中文顺序进行排序后返回。

可以使用Collator这个类。

Collator

Collator是java.text 包中的一个抽象类,专门用于执行与语言环境相关的字符串比较。

它能够根据特定语言或地区的规则对字符串进行排序和比较,

解决了简单按Unicode码点比较不适用于自然语言排序的问题

  1. 核心作用

语言敏感的字符串比较:支持拼音、笔画等本地化排序规则

Unicode标准实现:符合CLDR(Common Locale Data Repository)规范

  1. 关键构造方法

getInstance() 默认语言环境的比较器 Collator.getInstance()

getInstance(Locale) 指定语言环境

Locale.CHINA(中文)

Locale.TAIWAN(繁体)

  1. 排序强度控制(重要)

    collator.setStrength(Collator.PRIMARY); // 仅比较基础字母(忽略音调/大小写)

    collator.setStrength(Collator.SECONDARY); // 区分音调(如ā vs á)

    collator.setStrength(Collator.TERTIARY); // 全区分(默认,包括大小写)

中文场景建议:PRIMARY(拼音首字母)或SECONDARY(完整拼音)

  1. 性能优化技巧

    // 复用Collator实例(线程不安全,需配合ThreadLocal)
    private static final ThreadLocal<Collator> COLLATOR =
    ThreadLocal.withInitial(() -> Collator.getInstance(Locale.CHINA));

5、生产环境增强建议

多音字处理

复制代码
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);  // 处理"重庆"等多音字

混合语言排序// 中英文混合排序策略

复制代码
Comparator<CurrentStoreAllUsersDTO> comparator = (o1, o2) -> {
    if (isChinese(o1.getName())  && isChinese(o2.getName()))  {
        return collator.compare(o1.getName(),  o2.getName());
    }
    return o1.getName().compareTo(o2.getName());
};

扩展排序规则

复制代码
// 先按部门排序,再按姓名拼音排序
Comparator.comparing(CurrentStoreAllUsersDTO::getDept)
         .thenComparing(dto -> dto.getShiftExchangeUserName(),  collator)

6、其他方案

(1)Pinyin4j

可获取拼音首字母,定制性强

需引入第三方库,多音字处理复杂

(2)数据库排序

性能高,利用索引

依赖数据库配置,灵活性差

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

新建业务测试实体类

复制代码
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;


@Data
@Builder
@Accessors(chain = true)
public class CurrentStoreAllUsersDTO {

    private String shiftExchangeUserId;

    private String shiftExchangeUserName;

}

新建排序方法

复制代码
    /**
     * 按中文姓名拼音升序排序(A-Z)
     * @param list 待排序的DTO列表
     * @return 排序后的新列表
     */
    public static List<CurrentStoreAllUsersDTO> sortByNameChineseAZ(List<CurrentStoreAllUsersDTO> list) {
        Collator collator = Collator.getInstance(Locale.CHINA);  // 中文拼音比较器
        //排序强度控制
        collator.setStrength(Collator.PRIMARY);  // 忽略音调差异
        collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);  // 处理多音字
        return Optional.ofNullable(list)
                .orElseGet(ArrayList::new)
                .stream()
                .filter(Objects::nonNull)
                .filter(dto -> StringUtils.isNotBlank(dto.getShiftExchangeUserName()))
                .sorted(Comparator.comparing(
                        dto -> StringUtils.defaultIfEmpty(dto.getShiftExchangeUserName(),  ""),
                        collator
                ))
                .collect(Collectors.toList());
    }

调用示例

复制代码
        //测试数据
        List<CurrentStoreAllUsersDTO> users = List.of(
                CurrentStoreAllUsersDTO.builder().shiftExchangeUserName("张三姨").build(),
                CurrentStoreAllUsersDTO.builder().shiftExchangeUserName("李四姨").build(),
                CurrentStoreAllUsersDTO.builder().shiftExchangeUserName("王五姨").build(),
                CurrentStoreAllUsersDTO.builder().shiftExchangeUserName("阿姨").build(),
                CurrentStoreAllUsersDTO.builder().shiftExchangeUserName("").build(),
                CurrentStoreAllUsersDTO.builder().build()
        );

        List<CurrentStoreAllUsersDTO> currentStoreAllUsersDTOS1 = sortByNameChineseAZ(users);

        System.out.println(currentStoreAllUsersDTOS1);

关键部分讲解

1、Optional.ofNullable(list).orElseGet(ArrayList::new)

防御式编程:通过Optional处理输入list为null的情况

惰性初始化:orElseGet比orElse更高效(避免不必要的对象创建)

等效传统写法

复制代码
if (list == null) {
    list = new ArrayList<>();
}
  1. 数据清洗层

    .filter(Objects::nonNull)
    .filter(dto -> StringUtils.isNotBlank(dto.getShiftExchangeUserName()))

3、核心排序层

复制代码
                .sorted(Comparator.comparing(
                        dto -> StringUtils.defaultIfEmpty(dto.getShiftExchangeUserName(),  ""),
                        collator
                ))

字段提取:通过Lambda表达式获取DTO中的用户名

空名字段处理:StringUtils.defaultIfEmpty 将null或空字符串转为""(避免NPE)

中文排序:Collator实例实现拼音序比较(比String.compareTo 更符合中文习惯)

注意这里的StringUtils是import org.apache.commons.lang3.StringUtils;

相关推荐
FQNmxDG4S38 分钟前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
前端老石人1 小时前
HTML 字符引用完全指南
开发语言·前端·html
matlab_xiaowang1 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
虹科网络安全1 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
axng pmje2 小时前
Java语法进阶
java·开发语言·jvm
rKWP8gKv72 小时前
Java微服务性能监控:Prometheus与Grafana集成方案
java·微服务·prometheus
老前端的功夫2 小时前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python
qq_435287922 小时前
第9章 夸父逐日与后羿射日:死循环与进程终止?十个太阳同时值班的并行冲突
java·开发语言·git·死循环·进程终止·并行冲突·夸父逐日
小江的记录本2 小时前
【Kafka核心】架构模型:Producer、Broker、Consumer、Consumer Group、Topic、Partition、Replica
java·数据库·分布式·后端·搜索引擎·架构·kafka
止语Lab2 小时前
从手动到框架:Go DI 演进的三个拐点
开发语言·后端·golang