You need to enable JavaScript to run this app. 如何实现Java自定义尺寸字符串Comparator完成带单位字符串排序
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Java自定义尺寸字符串Comparator完成带单位字符串排序

实现方案

核心逻辑是先把每个待比较的字符串拆分为数值部分和单位部分,再按规则分步比较:

  • 第一步比较单位的字典序,g天然排在ml前面
  • 单位相同时,比较数值大小,按升序排列

完整代码实现

import java.math.BigDecimal;

protected int compareInstances(String instance1, String instance2) {
    // 拆分instance1的数值和单位
    String[] split1 = splitValueAndUnit(instance1);
    BigDecimal value1 = new BigDecimal(split1[0]);
    String unit1 = split1[1];

    // 拆分instance2的数值和单位
    String[] split2 = splitValueAndUnit(instance2);
    BigDecimal value2 = new BigDecimal(split2[0]);
    String unit2 = split2[1];

    // 先按单位字典序排序
    int unitCompare = unit1.compareTo(unit2);
    if (unitCompare != 0) {
        return unitCompare;
    }

    // 单位相同则按数值升序排序,用BigDecimal避免浮点精度问题
    return value1.compareTo(value2);
}

/**
 * 拆分字符串为数值部分和单位部分
 * @param str 待拆分的字符串,格式为[数字][单位],例如50ml、100g
 * @return 长度为2的数组,下标0是数值字符串,下标1是单位字符串
 */
private String[] splitValueAndUnit(String str) {
    // 找到第一个非数字、非小数点的位置,就是单位的起始位置
    int unitStartIndex = 0;
    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        if (!Character.isDigit(c) && c != '.') {
            unitStartIndex = i;
            break;
        }
    }
    String valueStr = str.substring(0, unitStartIndex);
    String unitStr = str.substring(unitStartIndex);
    return new String[]{valueStr, unitStr};
}

逻辑说明

  1. 拆分逻辑:遍历字符串找到第一个既不是数字也不是小数点的位置,以此为界拆分数值和单位,适配整数、小数的数值格式
  2. 单位比较直接用String自带的字典序比较,刚好符合g排在ml前面的要求
  3. 数值比较用BigDecimal而不是double/float,避免小数精度丢失导致排序错误
  4. 如果业务场景存在不符合格式的输入,可以在splitValueAndUnit方法里增加异常捕获,异常时直接返回原字符串的compareTo结果作为兜底即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 07:06:02