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

Java 實現中英混合字串陣列按首字母排序:拼音輔助排序法

     編輯:Java 相關知識

問題背景

Java 預設 Arrays.sort() 配合 Collator.getInstance(Locale.CHINA) 排序規則為:數字 → 英文 → 漢字。但在通訊錄、音樂列表等場景,期望 英文首字母與漢字拼音首字母合併排序(如 "Apple" 與 "安卓" 同歸 A 區)。

核心思路:拼音首字母前綴法

  1. 遍歷陣列,檢測字串首字元是否為漢字 (正則 [\u4e00-\u9fa5])
  2. 若為漢字,使用 pinyin4j 庫獲取首字拼音首字母 (小寫)
  3. 在字串前加上 首字母& 作為排序鍵,例如 "a&安卓"
  4. 使用 JDK 原生排序 (已設定 Locale.CHINA)
  5. 排序後移除前綴,還原原始字串

完整實作代碼

import java.util.*;
import net.sourceforge.pinyin4j.*;
import net.sourceforge.pinyin4j.format.*;

public class MixedStringSorter {
    public static void main(String[] args) {
        String[] arrays = {"gyu", "sdf", "zf", "大同", "收到", "中央", "三等分", 
                          "的人", "支持高鐵", "泛代數", "上的投入", "和國度"};
        
        // 步驟 1:為漢字開頭字串加上拼音首字母前綴
        for (int i = 0; i < arrays.length; i++) {
            String str = arrays[i];
            if (str.isEmpty()) continue;
            String firstChar = str.substring(0, 1);
            if (firstChar.matches("[\\u4e00-\\u9fa5]+")) {
                String initial = getPinyinInitial(str);
                arrays[i] = initial + "&" + str; // 如 "d&大同"
            }
        }
        
        // 步驟 2:設定中文語系環境並排序
        Comparator cmp = Collator.getInstance(Locale.CHINA);
        Arrays.sort(arrays, cmp);
        
        // 步驟 3:移除前綴並輸出
        for (int i = 0; i < arrays.length; i++) {
            String s = arrays[i];
            if (s.contains("&") && s.indexOf("&") == 1) {
                arrays[i] = s.split("&")[1];
            }
            System.out.println(arrays[i]);
        }
    }
    
    // 獲取漢字字串首字的拼音首字母 (小寫)
    private static String getPinyinInitial(String str) {
        HanyuPinyinOutputFormat fmt = new HanyuPinyinOutputFormat();
        fmt.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        fmt.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            String[] pinyinArr = PinyinHelper.toHanyuPinyinStringArray(str.charAt(0), fmt);
            return pinyinArr[0].substring(0, 1); // 取首字母
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
            return "#"; // 異常情況置於最後
        }
    }
}

執行結果

大同
的人
中央
支持高鐵
泛代數
gyu
和國度
三等分
上的投入
收到
sdf
zf

達到「拼音首字母與英文首字母混排」效果:d(大同) → r(的人) → z(中央) → z(支持) → f(泛) → g(gyu) → h(和) → s(三) → s(上) → s(收) → s(sdf) → z(zf)。

依賴與替代方案

  • Maven 依賴:com.belerweb:pinyin4j:2.5.0
  • 無第三方庫方案:自建漢字→拼音映射表 (僅覆蓋常用字) 或使用 JDK 9+ java.text.Normalizer 配合 Unicode 區段判斷 (較複雜)。
  • ICU4J:com.ibm.icu.text.Transliterator.getInstance("Han-Latin") 可轉換整串拼音,功能更強大。

效能與遷就

  • 時間複雜度:O(n log n) 排序 + O(n * m) 拼音轉換 (m 為字串長度,實際只取首字)
  • 空間:O(n) 額外陣列
  • 適用於靜態資料、中小規模陣列 (萬筆以內)。大規模高頻排序建議預先計算排序鍵並快取。

總結

利用「拼音首字母前綴 + JDK 原生排序 + 後處理移除」的巧妙組合,避免了自寫複雜比較器的風險,以最少代碼實現中英混合首字母合併排序,是實務中極具性價比的解法。

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