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

基于Java 8实现带多下划线的字符串列表按整数规则排序

问题描述

需要仅使用Java 8对包含多个下划线的String类型ArrayList按整数规则排序,原始数据示例如下:

List<String> keyValues = new ArrayList<String>();
keyValues.add("100_10_20_1");
keyValues.add("100001");
keyValues.add("100002");
keyValues.add("100002_1");
keyValues.add("100003");
keyValues.add("100");
keyValues.add("100_1");
keyValues.add("100_2");
keyValues.add("100_1_1");
keyValues.add("100_10_20");
keyValues.add("10000001");
keyValues.add("100_10_20_2");

此前尝试过将下划线替换为0或空字符串,但会出现数值冲突;替换为点转为Double类型则触发异常。指定的排序逻辑为:前缀相同的短字符串排在前面,同一前缀下按后续整数值从小到大排序,示例逻辑如下:

100
100_1
100_1_2 
/after that only/
100_2
100_2_2
/after that/
103
104
105
10000
/similarly the pattern repeats/
10000_1
10000_2
10000_2_1
100002

期望排序结果:

100
100_1
100_1_1
100_2
100_10_20
100_10_20_1
100_10_20_2
100001
100002
100002_1
100003
10000001
解决方案

核心思路是将每个字符串按下划线分割为整数数组,然后逐个比较数组中的元素:

  1. 依次比较两个数组对应位置的整数值,遇到不同值直接返回比较结果
  2. 如果一个数组是另一个的前缀,则短数组对应的字符串排在前面

具体实现代码如下:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class StringIntegerSort {
    public static void main(String[] args) {
        List<String> keyValues = new ArrayList<>();
        keyValues.add("100_10_20_1");
        keyValues.add("100001");
        keyValues.add("100002");
        keyValues.add("100002_1");
        keyValues.add("100003");
        keyValues.add("100");
        keyValues.add("100_1");
        keyValues.add("100_2");
        keyValues.add("100_1_1");
        keyValues.add("100_10_20");
        keyValues.add("10000001");
        keyValues.add("100_10_20_2");

        // Java 8 排序实现
        List<String> sortedList = keyValues.stream()
                .sorted(Comparator.comparing(
                        s -> java.util.Arrays.stream(s.split("_"))
                                .map(Long::parseLong)
                                .collect(Collectors.toList()),
                        (list1, list2) -> {
                            int minLength = Math.min(list1.size(), list2.size());
                            for (int i = 0; i < minLength; i++) {
                                int compare = list1.get(i).compareTo(list2.get(i));
                                if (compare != 0) {
                                    return compare;
                                }
                            }
                            // 短列表在前
                            return Integer.compare(list1.size(), list2.size());
                        }
                ))
                .collect(Collectors.toList());

        // 输出结果
        sortedList.forEach(System.out::println);
    }
}

代码说明

  • 使用split("_")将字符串分割为子串,再转为Long类型(避免整数溢出,比如10000001这类大数值)
  • 自定义Comparator比较两个整数列表:先逐一比较对应位置的数值,若全部相同则比较列表长度,短列表对应的字符串排在前面
  • 完全基于Java 8的Stream和Lambda表达式实现,符合要求

运行上述代码后,输出结果与期望一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:55:33