字符串版本号比较(Java)

APP的版本升级更新,会用到版本号的对比。根据版本号去解析埋点上报得信息。

正则匹配方式解析版本号中字符和数字做对比,默认字符大于数字(版本号1 是否大于等于 版本号2)。详见以下代码

@Slf4j
public class CompareUtil {

    private static final Pattern num = Pattern.compile("[^0-9]");
    private static final Pattern cha = Pattern.compile("\\D+");

    /**
     * 版本号对比, 默认字符大于数字: 如("10.0.1b", "10.0.1a")
     * @param ver1 版本号1
     * @param ver2 版本号2
     * @return 版本号1 是否大于等于 版本号2
     */
    public static boolean versionCompare(String ver1, String ver2) {

        ver1 = StringUtils.isEmpty(ver1) ? "99.99": ver1;
        ver2 = StringUtils.isEmpty(ver2) ? "99.99": ver2;

        String[] verA = ver1.split("\\.", -1);
        String[] verB = ver2.split("\\.", -1);

        int com;
        int len = Math.max(verA.length, verB.length);
        // 补齐字符串数组
        if (verA.length < len)
            verA = stringExt(verA, len);
        else if (verB.length < len)
            verB = stringExt(verB, len);

        for (int i = 0; i < len; i++) {
            try {
                com = Integer.parseInt(verA[i]) - Integer.parseInt(verB[i]);
            } catch (Exception e) {
                log.error(String.format("versionCompare err: ver1=>%s, ver1=>%s", ver1, ver2), e);
                com = numAndCharCompare(verA[i], verB[i]);
            }

            if (com > 0) return true;
            else if (com < 0) return false;
        }


        return true;
    }

    /**
     * 数字与字符组成字符串大小比较,如:(10a 9a),(9a 9),(9b 9a)
     * @param left
     * @param right
     * @return 1、0、-1
     */
    public static int numAndCharCompare(String left, String right) {

        left = left.length() == 0 ? "0" : left;
        right = right.length() == 0 ? "0" : right;

        // 判断字符串首字符是否为数字
        boolean bL = left.charAt(0) >= 48 && left.charAt(0) <= 57;
        boolean bR = right.charAt(0) >= 48 && right.charAt(0) <= 57;
        if (bL && !bR)
            return -1;
        else if (!bL && bR)
            return 1;

        // 获取数字
        String[] numLeft  = num.matcher(left).replaceAll(",").split(",");
        String[] numRight = num.matcher(right).replaceAll(",").split(",");

        // 获取字符串
        List<String> charLeft = new ArrayList<>();
        List<String> charRight = new ArrayList<>();
        Matcher matcherL = cha.matcher(left);
        Matcher matcherR = cha.matcher(right);
        while (matcherL.find()) {
            charLeft.add(matcherL.group(0));
        }
        while (matcherR.find()) {
            charRight.add(matcherR.group(0));
        }

        int numL = numLeft.length;
        int numR = numRight.length;
        int numLen = Math.max(numL, numR);
        // 补齐字符串数组
        if (numL < numLen)
            numLeft = stringExt(numLeft, numLen);
        else if (numR < numLen)
            numRight = stringExt(numRight, numLen);


        // 补齐List
        int charL = charLeft.size();
        int charR = charRight.size();
        int charMax = Math.max(charL, charR);
        if (charL < charMax)
            listExt(charLeft, charL, charMax);
        else if (charR < charMax)
            listExt(charRight, charR, charMax);

        int com = 0;
        if (bL) // 同为数字开头
        {
            for (int i = 0; i < numLen; i++) {
                com = Integer.parseInt(numLeft[i]) - Integer.parseInt(numRight[i]);
                if (com == 0 && i < charMax)
                    com = charLeft.get(i).compareTo(charRight.get(i));

                if (com > 0) return 1;
                else if (com < 0) return -1;
            }
        }
        else {
            for (int i = 0; i < charMax; i++){
                com = charLeft.get(i).compareTo(charRight.get(i));
                if (com == 0 && i < numLen)
                    com = Integer.parseInt(numLeft[i+1]) - Integer.parseInt(numRight[i+1]);

                if (com > 0) return 1;
                else if (com < 0) return -1;
            }
        }

        return 0;
    }

    /**
     * 补齐字符串数组长度
     * @param data 字符串数组
     * @param len 补齐长度
     * @return 补齐后的数组
     */
    public static String[] stringExt(String[] data, int len) {
        String[] res = new String[len];

        int index = 0;
        for (String datum : data) {
            res[index++] = datum;
        }

        while (index < len){
            res[index++] = "0";
        }

        return res;
    }

    /**
     * 补齐List长度
     * @param data list
     * @param size 自身长度
     * @param len 补齐长度
     */
    public static void listExt(List<String> data, int size, int len) {
        while (size < len) {
            data.add("0");
            size++;
        }
    }


    public static void main(String[] args) {
        System.out.println(versionCompare("10.0.0", "10.0.0"));
        System.out.println(versionCompare("10.0.0", "9.0.0"));
        System.out.println(versionCompare("10.1.0", "10.0.0"));
        System.out.println(versionCompare("10.0.1b", "10.0.1a"));
        System.out.println(versionCompare("10.0._0", "10.0._0_"));
        System.out.println(versionCompare("9..", "9.0.0"));
    }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值