介绍
最近在做好友列表的时候,仿照微信的好友列表,A-Z索引,需要用到好友名字的拼音,之前已经有封装好拼音的工具类,但是最近发现对于一些多音字,姓氏的处理没有做到位,比如姓氏单(shan),由于对于多音字没有做一些处理,仅仅只是取多音字列表的第一个,所以取到的拼音是dan,所以利用空闲的时间对这个拼音的工具类进行了处理。
常见姓氏拼音
SimpleArrayMapsurnames = 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");复制代码
效果图
拼音的获取
上图获取的拼音内容如下:
pinyin: QINTANGpinyin: QIULANpinyin: SHANDANpinyin: ZENGERpinyin: #复制代码
可以看到姓氏的拼音是正确的,最后一个由于不是以汉字开头,所以其拼音的内容是#
获取拼音的方法
public static String getPinyin(String str) { // 设置拼音结果的格式 HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.UPPERCASE);// 设置为大写形式 format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);// 不用加入声调 StringBuilder sb = new StringBuilder(); char[] charArray = str.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (Character.isWhitespace(c)) {// 如果是空格则跳过 continue; } if (isHanZi(c)) {// 如果是汉字 String s = ""; try { if (i == 0){ //如果是第一个,则使用获取姓氏 s = getSurnamePinyin(String.valueOf(c)); }else{ // toHanyuPinyinStringArray 返回一个字符串数组是因为该汉字可能是多音字,此处只取第一个结果 s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0]; } sb.append(s); } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); sb.append(s); } } else { // 不是汉字 if (i == 0) { if (isEnglish(c)) {// 第一个属于字母,则返回该字母 return String.valueOf(c).toUpperCase(Locale.ENGLISH); } return "#"; // 不是的话返回#号 } } } return sb.toString(); }复制代码
主要的逻辑是,将字符串拆解成字符数组,遍历每个字符:
- 如果第一个是汉字,则获取调用getSurnamePinyin()方法,获取其对应的拼音,这个方法主要是对姓氏的处理;
- 如果第一个字符是英文,则直接返回该字符的大写;
- 如果第一个字符不是汉字也不是英文,则直接返回"#"号;
如何判断是否是汉字
public static boolean isHanZi(char c) { Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+"); Matcher matcher = pattern.matcher(String.valueOf(c)); return matcher.matches(); }复制代码
通过如上方法,使用正则表达式匹配,如果满足,则说明是汉字,返回true。
如何判断是否是英文
public static boolean isEnglish(char c) { return String.valueOf(c).matches("^[a-zA-Z]*"); }复制代码
获取姓氏的拼音
public static String getSurnamePinyin(CharSequence name) { if (name == null || name.length() == 0) return null; char ch = name.charAt(0); if (surnames.containsKey(ch)) { String s = surnames.get(ch); return s.toUpperCase(Locale.ENGLISH); } if (ch >= 0x4E00 && ch <= 0x9FA5) { int sp = (ch - 0x4E00) * 6; return pinyinTable.substring(sp, sp + 6).trim().toUpperCase(Locale.ENGLISH); } else { return String.valueOf(ch).toUpperCase(Locale.ENGLISH); } }复制代码
通过查找已经存储在map中对应姓氏的拼音
相关代码
PinyinUtils代码:
依赖到的jar包,pinyin4j-2.5.0.jar下载: