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

Java 實現字母數字混合字符串的自然排序比較

     編輯:Java 相關知識

前言

在 Java 開發中,常會遇到類似 a20 和 a9 這樣的字母數字混合字符串。若直接使用 String.compareTo(),結果會是 a20 < a9(按字典序),但業務上往往期望 a20 > a9(按數值大小)。這就是典型的「自然排序」需求,也是常見的面試題目。

核心思路

  1. 拆分字符串:將字符串按「連續字母」與「連續數字」切分,轉換為一個 List<Object>,其中數字部分存為 Integer,字母部分存為 String(或 StringBuffer)。
  2. 逐元素比較:遍歷兩個列表,對應位置若都是數字則按數值比較;若都是字符串則按字典序比較;類型不同則數字視為小於字母(或根據業務定義)。
  3. 兜底處理:若前綴完全相同,則退回到原始字符串的 compareTo,以處理 a02 vs a2 這類前導零情況。

關鍵實現細節

1. 字符串解析為列表

採用單次遍歷,利用 StringBuffer 暫存字母,Integer 累加數字。遇到類型切換時,將暫存內容加入列表並重置暫存器。

2. 比較邏輯

@Override
public int compareTo(MyString another) {
    int n = Math.min(list.size(), another.list.size());
    for (int i = 0; i < n; i++) {
        Object o1 = list.get(i), o2 = another.list.get(i);
        int cmp;
        if (o1 instanceof Integer && o2 instanceof Integer) {
            cmp = (Integer)o1 - (Integer)o2;
        } else {
            cmp = o1.toString().compareTo(o2.toString());
        }
        if (cmp != 0) return cmp;
    }
    // 前綴相同,按原始字符串比較(保留前導零差異)
    return compareToLikeString(another.string);
}

3. 處理前導零

若直接用 string.compareTo(another.string),a02 會小於 a2(因 '0' < '2')。自定義 compareToLikeString 可按字符逐個比較,若完全相同再比長度,確保 a02 > a2 符合直覺。

完整代碼示例

public class MyString implements Comparable<MyString> {
    private final String string;
    private final List<Object> list = new ArrayList<>();

    public MyString(String string) {
        this.string = string;
        parse();
    }

    private void parse() {
        StringBuffer sb = new StringBuffer();
        int num = 0;
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);
            if (c >= '0' && c <= '9') {
                if (sb.length() > 0) { list.add(sb.toString()); sb.setLength(0); }
                num = num * 10 + (c - '0');
            } else {
                if (num != 0) { list.add(num); num = 0; }
                sb.append(c);
            }
        }
        if (sb.length() > 0) list.add(sb.toString());
        else if (num != 0) list.add(num);
    }

    // ... compareTo 實現同上 ...
}

測試驗證

MyString m1 = new MyString("b9c");
MyString m2 = new MyString("b09c");
System.out.println(m1.compareTo(m2)); // 輸出 > 0,表示 b9c > b09c

總結

通過實現 Comparable 接口並結合「字母數字分離解析 + 逐元素比較」策略,即可優雅解決混合字符串的自然排序問題。此方案可擴展至文件名排序、版本號比較等場景。

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