工具類之PinyinUtils

前言:年底了,最近都比較忙,每天能抽出的時間也有點少,而且,現(xiàn)在都在努力解決之前的bug,由于github上有同志提出來了拼音工具類有部分漢字識別出錯,這不,趁這兩天借鑒了其他的實現(xiàn)方式,立馬開車擼碼,因為大部分是用在跟姓氏相關(guān),所以對姓氏做了多音字,普通的拼音識別并沒有多音字識別哦,如需實現(xiàn),那就依賴第三方開源庫--pinyin4j吧,緊接著,那就發(fā)車咯。

上車須知

首先先看下單元測試吧,看是否入老司機們的法眼。

澹臺: tantai
尉遲: yuchi
萬俟: moqi
單于: chanyu
樂 正確: yue    首字母: y      錯誤: le    
乘 正確: sheng  首字母: s      錯誤: cheng 
乜 正確: nie    首字母: n      錯誤: mie   
仇 正確: qiu    首字母: q      錯誤: chou  
會 正確: gui    首字母: g      錯誤: hui   
便 正確: pian   首字母: p      錯誤: bian  
區(qū) 正確: ou     首字母: o      錯誤: qu    
單 正確: shan   首字母: s      錯誤: dan   
參 正確: shen   首字母: s      錯誤: can   
句 正確: gou    首字母: g      錯誤: ju    
召 正確: shao   首字母: s      錯誤: zhao  
員 正確: yun    首字母: y      錯誤: yuan  
宓 正確: fu     首字母: f      錯誤: mi    
弗 正確: fei    首字母: f      錯誤: fu    
折 正確: she    首字母: s      錯誤: zhe   
曾 正確: zeng   首字母: z      錯誤: ceng  
樸 正確: piao   首字母: p      錯誤: po    
查 正確: zha    首字母: z      錯誤: cha   
洗 正確: xian   首字母: x      錯誤: xi    
蓋 正確: ge     首字母: g      錯誤: gai   
祭 正確: zhai   首字母: z      錯誤: ji    
種 正確: chong  首字母: c      錯誤: zhong 
秘 正確: bi     首字母: b      錯誤: mi    
繁 正確: po     首字母: p      錯誤: fan   
繆 正確: miao   首字母: m      錯誤: mou   
能 正確: nai    首字母: n      錯誤: neng  
蕃 正確: pi     首字母: p      錯誤: fan   
覃 正確: qin    首字母: q      錯誤: tan   
解 正確: xie    首字母: x      錯誤: jie   
諶 正確: shan   首字母: s      錯誤: chen  
適 正確: kuo    首字母: k      錯誤: shi   
都 正確: du     首字母: d      錯誤: dou   
阿 正確: e      首字母: e      錯誤: a     
難 正確: ning   首字母: n      錯誤: nan   
黑 正確: he     首字母: h      錯誤: hei   
用時: 14ms
單元測試: d,y,c,s,
單: d
元: y
測: c
試: s
已初始化的漢字轉(zhuǎn)拼音用時測試: yi chu shi hua de han zi zhuan pin yin yong shi ce shi 
用時: 0ms

站點

ccs2Pinyin           : 漢字轉(zhuǎn)拼音
ccs2Pinyin           : 漢字轉(zhuǎn)拼音
getPinyinFirstLetter : 獲取第一個漢字首字母
getPinyinFirstLetters: 獲取所有漢字的首字母
getSurnamePinyin     : 根據(jù)名字獲取姓氏的拼音
getSurnameFirstLetter: 根據(jù)名字獲取姓氏的首字母

具體路線

import android.support.v4.util.SimpleArrayMap;

/**
 * <pre>
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 16/11/16
 *     desc  : 拼音相關(guān)工具類
 * </pre>
 */
public class PinyinUtils {

    private PinyinUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 漢字轉(zhuǎn)拼音
     *
     * @param ccs 漢字字符串(Chinese characters)
     * @return 拼音
     */
    public static String ccs2Pinyin(CharSequence ccs) {
        return ccs2Pinyin(ccs, "");
    }

    /**
     * 漢字轉(zhuǎn)拼音
     *
     * @param ccs   漢字字符串(Chinese characters)
     * @param split 漢字拼音之間的分隔符
     * @return 拼音
     */
    public static String ccs2Pinyin(CharSequence ccs, CharSequence split) {
        if (ccs == null || ccs.length() == 0) return null;
        StringBuilder sb = new StringBuilder();
        for (int i = 0, len = ccs.length(); i < len; i++) {
            char ch = ccs.charAt(i);
            if (ch >= 0x4E00 && ch <= 0x9FA5) {
                int sp = (ch - 0x4E00) * 6;
                sb.append(pinyinTable.substring(sp, sp + 6).trim());
            } else {
                sb.append(ch);
            }
            sb.append(split);
        }
        return sb.toString();
    }

    /**
     * 獲取第一個漢字首字母
     *
     * @param ccs 漢字字符串(Chinese characters)
     * @return 拼音
     */
    public static String getPinyinFirstLetter(CharSequence ccs) {
        if (ccs == null || ccs.length() == 0) return null;
        return ccs2Pinyin(String.valueOf(ccs.charAt(0))).substring(0, 1);
    }

    /**
     * 獲取所有漢字的首字母
     *
     * @param ccs 漢字字符串(Chinese characters)
     * @return 所有漢字的首字母
     */
    public static String getPinyinFirstLetters(CharSequence ccs) {
        return getPinyinFirstLetters(ccs, "");
    }

    /**
     * 獲取所有漢字的首字母
     *
     * @param ccs   漢字字符串(Chinese characters)
     * @param split 首字母之間的分隔符
     * @return 所有漢字的首字母
     */
    public static String getPinyinFirstLetters(CharSequence ccs, CharSequence split) {
        if (ccs == null || ccs.length() == 0) return null;
        int len = ccs.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            sb.append(ccs2Pinyin(String.valueOf(ccs.charAt(i))).substring(0, 1)).append(split);
        }
        return sb.toString();
    }

    /**
     * 根據(jù)名字獲取姓氏的拼音
     *
     * @param name 名字
     * @return 姓氏的拼音
     */
    public static String getSurnamePinyin(CharSequence name) {
        if (name == null || name.length() == 0) return null;
        if (name.length() >= 2) {
            CharSequence str = name.subSequence(0, 2);
            if (str.equals("澹臺")) return "tantai";
            else if (str.equals("尉遲")) return "yuchi";
            else if (str.equals("萬俟")) return "moqi";
            else if (str.equals("單于")) return "chanyu";
        }
        char ch = name.charAt(0);
        if (surnames.containsKey(ch)) {
            return surnames.get(ch);
        }
        if (ch >= 0x4E00 && ch <= 0x9FA5) {
            int sp = (ch - 0x4E00) * 6;
            return pinyinTable.substring(sp, sp + 6).trim();
        } else {
            return String.valueOf(ch);
        }
    }

    /**
     * 根據(jù)名字獲取姓氏的首字母
     *
     * @param name 名字
     * @return 姓氏的首字母
     */
    public static String getSurnameFirstLetter(CharSequence name) {
        String surname = getSurnamePinyin(name);
        if (surname == null || surname.length() == 0) return null;
        return String.valueOf(surname.charAt(0));
    }

    // 多音字姓氏映射表
    private static final SimpleArrayMap<Character, String> surnames;

    /**
     * 獲取拼音對照表,對比過pinyin4j和其他方式,這樣查表設(shè)計的好處就是讀取快
     * <p>當(dāng)該類加載后會一直占有123KB的內(nèi)存</p>
     * <p>如果你想存進文件,然后讀取操作的話也是可以,但速度肯定沒有這樣空間換時間快,畢竟現(xiàn)在設(shè)備內(nèi)存都很大</p>
     * <p>如需更多用法可以用pinyin4j開源庫</p>
     */
    private static final String pinyinTable;

    static {
        surnames = new SimpleArrayMap<>(35);
        surnames.put('樂', "yue");
        surnames.put('乘', "sheng");
        surnames.put('乜', "nie");
        surnames.put('仇', "qiu");
        surnames.put('會', "gui");
        surnames.put('便', "pian");
        surnames.put('區(qū)', "ou");
        surnames.put('單', "shan");
        surnames.put('參', "shen");
        surnames.put('句', "gou");
        surnames.put('召', "shao");
        surnames.put('員', "yun");
        surnames.put('宓', "fu");
        surnames.put('弗', "fei");
        surnames.put('折', "she");
        surnames.put('曾', "zeng");
        surnames.put('樸', "piao");
        surnames.put('查', "zha");
        surnames.put('洗', "xian");
        surnames.put('蓋', "ge");
        surnames.put('祭', "zhai");
        surnames.put('種', "chong");
        surnames.put('秘', "bi");
        surnames.put('繁', "po");
        surnames.put('繆', "miao");
        surnames.put('能', "nai");
        surnames.put('蕃', "pi");
        surnames.put('覃', "qin");
        surnames.put('解', "xie");
        surnames.put('諶', "shan");
        surnames.put('適', "kuo");
        surnames.put('都', "du");
        surnames.put('阿', "e");
        surnames.put('難', "ning");
        surnames.put('黑', "he");

        pinyinTable = new StringBuilder(125412).toString();//由于表太長,請參看源碼
    }
}

終點站

為了實現(xiàn)姓氏多音字,我也是大費周折地找了很多,如果你們覺得有所不足或錯誤,那么歡迎留言,好了,終點站到了,如果對本次旅途滿意的話,請給五星好評哦,畢竟老司機這次真的犧牲了很多時間才換來這么一份工具類,如果該工具類依賴其他工具類,都可以在我的Android開發(fā)人員不得不收集的代碼(持續(xù)更新中)中找到。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容