工具类之PinyinUtils
2016-12-17 本文已影响3938人
Blankj
前言:年底了,最近都比较忙,每天能抽出的时间也有点少,而且,现在都在努力解决之前的bug,由于github上有同志提出来了拼音工具类有部分汉字识别出错,这不,趁这两天借鉴了其他的实现方式,立马开车撸码,因为大部分是用在跟姓氏相关,所以对姓氏做了多音字,普通的拼音识别并没有多音字识别哦,如需实现,那就依赖第三方开源库--pinyin4j吧,紧接着,那就发车咯。
上车须知
首先先看下单元测试吧,看是否入老司机们的法眼。
澹台: tantai
尉迟: yuchi
万俟: moqi
单于: chanyu
乐 正确: yue 首字母: y 错误: le
乘 正确: sheng 首字母: s 错误: cheng
乜 正确: nie 首字母: n 错误: mie
仇 正确: qiu 首字母: q 错误: chou
会 正确: gui 首字母: g 错误: hui
便 正确: pian 首字母: p 错误: bian
区 正确: 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
已初始化的汉字转拼音用时测试: yi chu shi hua de han zi zhuan pin yin yong shi ce shi
用时: 0ms
站点
- 拼音相关→PinyinUtils.java→Test
ccs2Pinyin : 汉字转拼音
ccs2Pinyin : 汉字转拼音
getPinyinFirstLetter : 获取第一个汉字首字母
getPinyinFirstLetters: 获取所有汉字的首字母
getSurnamePinyin : 根据名字获取姓氏的拼音
getSurnameFirstLetter: 根据名字获取姓氏的首字母
具体路线
import android.support.v4.util.SimpleArrayMap;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 16/11/16
* desc : 拼音相关工具类
* </pre>
*/
public class PinyinUtils {
private PinyinUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* 汉字转拼音
*
* @param ccs 汉字字符串(Chinese characters)
* @return 拼音
*/
public static String ccs2Pinyin(CharSequence ccs) {
return ccs2Pinyin(ccs, "");
}
/**
* 汉字转拼音
*
* @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();
}
/**
* 根据名字获取姓氏的拼音
*
* @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);
}
}
/**
* 根据名字获取姓氏的首字母
*
* @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和其他方式,这样查表设计的好处就是读取快
* <p>当该类加载后会一直占有123KB的内存</p>
* <p>如果你想存进文件,然后读取操作的话也是可以,但速度肯定没有这样空间换时间快,毕竟现在设备内存都很大</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('区', "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();//由于表太长,请参看源码
}
}
终点站
为了实现姓氏多音字,我也是大费周折地找了很多,如果你们觉得有所不足或错误,那么欢迎留言,好了,终点站到了,如果对本次旅途满意的话,请给五星好评哦,毕竟老司机这次真的牺牲了很多时间才换来这么一份工具类,如果该工具类依赖其他工具类,都可以在我的Android开发人员不得不收集的代码(持续更新中)中找到。