前言:年底了,最近都比較忙,每天能抽出的時間也有點少,而且,現(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
站點
- 拼音相關(guān)→PinyinUtils.java→Test
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ù)更新中)中找到。