首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 版本號比較算法實現:支援字母後綴、多段位、語義化版本

     編輯:Java 相關知識

版本號比較難點

  • 非純數字:1.0.0-alpha, 2.5.6-rc.1, 8.5c。
  • 段數不定:1.0 vs 1.0.0.0。
  • 字符串比較陷阱:"9.9" > "10.8" (按字典序)。

通用比較規則

  1. 按分隔符 (通常為 .) 分割成段數組。
  2. 逐段比較:先比長度 (位數多者大),再按字符串自然序比較 (支援字母)。
  3. 前缀段全部相等時,段數多者視為較新 (如 1.0.0 > 1.0)。

核心實現 (Java 8+)


public final class VersionUtil {
    private VersionUtil() {}

    /**
     * 比較兩個版本號
     * @return v1 > v2 返回 1; v1 < v2 返回 -1; 相等返回 0
     */
    public static int compare(String v1, String v2) {
        if (v1 == null || v2 == null) throw new IllegalArgumentException("版本號不能為空");
        String[] s1 = v1.split("\\."); // 轉義 .
        String[] s2 = v2.split("\\.");
        int len = Math.min(s1.length, s2.length);

        for (int i = 0; i < len; i++) {
            String seg1 = s1[i];
            String seg2 = s2[i];
            // 先比長度 (數值位數)
            int cmp = Integer.compare(seg1.length(), seg2.length());
            if (cmp != 0) return cmp > 0 ? 1 : -1;
            // 長度相等,按字符串自然序 (支援字母、數字混合)
            cmp = seg1.compareTo(seg2);
            if (cmp != 0) return cmp > 0 ? 1 : -1;
        }
        // 前綴段完全相等,段數多者大
        return Integer.compare(s1.length, s2.length);
    }

    // 便捷方法
    public static boolean isGreater(String v1, String v2) { return compare(v1, v2) > 0; }
    public static boolean isLess(String v1, String v2) { return compare(v1, v2) < 0; }
    public static boolean isEqual(String v1, String v2) { return compare(v1, v2) == 0; }
}

測試用例驗證


@Test
public void testCompare() {
    assertEquals(1, VersionUtil.compare("10.8.8.6", "9.9"));       // 主版本位數不同
    assertEquals(1, VersionUtil.compare("9.9b", "9.8a"));          // 字母後綴
    assertEquals(1, VersionUtil.compare("1.0.0", "1.0"));          // 更多段數
    assertEquals(0, VersionUtil.compare("1.0.0", "1.0.0"));
    assertEquals(-1, VersionUtil.compare("1.0.0-alpha", "1.0.0")); // 字母 < 空/數字 (視具體規則)
}

進階:語義化版本 解析

若需嚴格遵循 SemVer 2.0 (Major.Minor.Patch[-PreRelease][+BuildMeta]),建議引入成熟庫:


// Maven

  com.github.zafarkhaja
  java-semver
  0.9.0


// 使用
Version v1 = Version.valueOf("1.0.0-alpha.1");
Version v2 = Version.valueOf("1.0.0");
v1.compareTo(v2); // -1

避坑指南

  1. 分割正則必須轉義:split("\\."),否則 . 匹配任意字符。
  2. 前導零處理:"1.05" vs "1.5",長度比較法視為 1.05 > 1.5;若需數值相等,先 Integer.parseInt 再比較 (但會丟失字母支持)。
  3. 非標準分隔符:某些項目用 -、_,按實際規範調整 split 參數。
  4. 大小寫敏感:compareTo 區分大小寫,統一規範為小寫或按 ASCII 序。

總結

版本號比較核心在於**「分段 → 比長度 → 比字典序 → 比段數」**。自行實現 20 行代碼即可覆蓋 90% 場景;嚴格 SemVer 合規項目請引入專用庫,避免邊界情況踩坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved