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

Java 如何基于字符串首个出现的数字对字符串数组进行数值排序

自定义字符串排序实现方案

问题本质

Arrays.sort()默认对字符串的比较逻辑是逐字符匹配的字典序,对比"1."、"18."、"2."时,会先比较开头的单个字符,判定"1."和"18."的开头字符排序小于"2.",不会把开头的连续数字整体当成数值做大小判断,最终得到不符合预期的排序结果。

核心实现逻辑

自定义排序规则的核心是绕开默认逐字符比较,针对每个字符串提取目标排序权重:

  • 定位每个字符串中第一个出现数字的位置
  • 截取从该位置开始的所有连续数字字符,转换为数值类型
  • 比较器直接基于提取出的数值做大小对比,完成排序

可直接使用的代码实现

import java.util.Arrays;
import java.util.regex.Pattern;

public class NumericSortDemo {
    // 预编译正则匹配首个连续数字段,减少重复编译的性能损耗
    private static final Pattern FIRST_NUM_PATTERN = Pattern.compile("\\d+");

    public static void main(String[] args) {
        String[] array = {
                "18.sdfahsdfkjadf",
                "1.skjfhadksfhad",
                "2.asldfalsdf"
        };

        Arrays.sort(array, (s1, s2) -> {
            int num1 = extractFirstNumber(s1);
            int num2 = extractFirstNumber(s2);
            return Integer.compare(num1, num2);
        });

        // 验证排序结果
        Arrays.stream(array).forEach(System.out::println);
    }

    private static int extractFirstNumber(String str) {
        var matcher = FIRST_NUM_PATTERN.matcher(str);
        if (matcher.find()) {
            return Integer.parseInt(matcher.group());
        }
        // 边界兜底:无数字的字符串统一排到队尾,可根据竞赛要求调整位置
        return Integer.MAX_VALUE;
    }
}

运行上述代码的输出结果完全符合预期:

1.skjfhadksfhad
2.asldfalsdf
18.sdfahsdfkjadf

场景适配优化

  • 若竞赛数据集规模较大,正则匹配的性能不足以满足时间要求,可以替换手动遍历的数字提取逻辑:逐字符扫描字符串,碰到第一个数字后持续拼接后续连续数字字符直到碰到非数字字符,解析为数值即可,运行效率更高
  • 若题目给出的字符串中首个数字段长度超过int类型的取值范围,需要替换为Long或BigInteger类型解析数值,避免溢出导致比较错误
  • 若题目要求首个数字段数值相等时,需按字符串原始字典序做次级排序,只需要在比较器中追加数值相等时的对比逻辑:if (num1 == num2) return s1.compareTo(s2);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 16:06:00