You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何对含字母数字属性的对象进行自然排序?

解决字符串含数字的自然排序问题

你遇到的是默认字典序排序与自然排序的差异问题。默认字符串比较会逐个对比字符ASCII码,"A-Product-12"里的第一个数字字符'1'比"A-Product-2"里的'2'ASCII码小,所以排序结果不符合预期。要实现按名称中数字的实际大小排序,需要自定义比较逻辑:

1. 自定义比较器实现自然排序

import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ProductNameComparator implements Comparator<Product> {
    // 匹配名称末尾数字的正则表达式
    private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)$");

    @Override
    public int compare(Product p1, Product p2) {
        // 提取名称中的数字部分
        Integer num1 = extractNumber(p1.name);
        Integer num2 = extractNumber(p2.name);
        
        // 先比较名称的非数字前缀
        String prefix1 = p1.name.replaceAll("\\d+$", "");
        String prefix2 = p2.name.replaceAll("\\d+$", "");
        
        int prefixCompare = prefix1.compareTo(prefix2);
        if (prefixCompare != 0) {
            return prefixCompare;
        }
        // 前缀相同时,按数字大小排序
        return num1.compareTo(num2);
    }

    private Integer extractNumber(String name) {
        Matcher matcher = NUMBER_PATTERN.matcher(name);
        if (matcher.find()) {
            return Integer.parseInt(matcher.group(1));
        }
        return 0; // 无数字时默认按0处理
    }
}

2. 应用自定义比较器排序

直接对列表排序

products.sort(new ProductNameComparator());

通过Stream流排序

List<Product> sortedProducts = products.stream()
    .sorted(new ProductNameComparator())
    .toList();

补充说明

如果产品名称中的数字位置不固定(比如中间也包含数字),可以调整正则表达式匹配所有数字段;若不想手动实现,也可以使用Apache Commons Lang工具包中的StringUtils.naturalCompare方法,但自定义比较器无需引入第三方依赖,完全能满足需求。

内容的提问来源于stack exchange,提问作者ardiafrizky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 04:15:42