需求背景:
老板希望搞出一款傻瓜工具:将汉字转成拼音,例如 杭州市西湖区-->hangzhoushixihuqu
或者是 -->hzsxhq
public static void main(String[] args) {
System.out.println(getFullPinyin("拼音测试数据!!!123"));
System.out.println(getFullPinyin("拼音测试数据!!!123", false));
System.out.println(getShortPinyin("拼音测试数据!!!123"));
System.out.println(getShortPinyin("拼音测试数据!!!123", false));
System.out.println(getShortPinyin("杭州市西湖区"));
System.out.println(getShortPinyin("屮"));
}
输出:
pinyinceshishuju!!!123
pinyinceshishuju
pycssj!!!123
pycssj
hzsxhq
c
解决方案:
1 引入转换工具 POM包
<!--拼音中文工具转换类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>
核心代码:
2 核心代码
/**
* 拼音-中文 转换工具类
*/
public class PingYingUtil {
/**
* 获取中文拼音首字母,其他字符不变
*
* @param str
* @return String
*/
public static String getShortPinyin(String str) {
return getShortPinyin(str, true);
}
/**
* 获取中文拼音首字母
*
* @param str
* @param retain 为true保留其他字符
* @return String
*/
public static String getShortPinyin(String str, boolean retain) {
return getPinyin(str, true, retain);
}
/**
* 获取中文拼音,其他字符不变
*
* @param str
* @return String
*/
public static String getFullPinyin(String str) {
return getFullPinyin(str, true);
}
/**
* 获取中文拼音
*
* @param str
* @param retain 为true保留其他字符
* @return String
*/
public static String getFullPinyin(String str, boolean retain) {
return getPinyin(str, false, retain);
}
/**
* 获取中文拼音
*
* @param str
* @param shortPinyin 为true获取中文拼音首字母
* @param retain 为true保留其他字符
* @return String
*/
private static String getPinyin(String str, boolean shortPinyin, boolean retain) {
if (StringUtils.isBlank(str)) {
return "";
}
StringBuffer pinyinBuffer = new StringBuffer();
char[] arr = str.toCharArray();
for (char c : arr) {
String[] temp = PinyinHelper.toHanyuPinyinStringArray(c);
if (ArrayUtils.isNotEmpty(temp)) {
if (StringUtils.isNotBlank(temp[0])) {
if (shortPinyin) {
pinyinBuffer.append(temp[0].charAt(0));
} else {
pinyinBuffer.append(temp[0].replaceAll("\d", ""));
}
}
} else {
if (retain) {
pinyinBuffer.append(c);
}
}
}
return pinyinBuffer.toString();
}
源码解析:
如 杭是如何变成 hang 的?
核心方法 PinyinHelper.toHanyuPinyinStringArray(c);
1 "杭".toCharArray() 转为字符数组 可以看到 杭 对应的十进制 unicode 编码是 26477
2 初始化一个包含 <Unicode, HanyuPinyin> 对的哈希表 也就是初始化 一份关系对应表
/pinyindb/unicode_to_hanyu_pinyin.txt
这里顺便点击进去看看这个表格是什么内容(看到这里应该就差不多了)
3 将杭的十进制 26477 转为16进制--> 676d
Integer.toHexString(codePointOfChar).toUpperCase();
4 根据 步骤2 维护的关系对应表 取出对应的拼音 -->杭--->hang
5 结束/验证
思考分析
整个过程其实就是在本地维护了一份 汉字的16进度与其拼音的对应表格,然后取出对应的数据 所以对应的缺点也是有的
例如1 多音字: 银行
public static void main(String[] args) {
System.out.println(getShortPinyin("银行"));
}
输出:
yx
例如2: 部分汉字依旧会缺失 ***** 但是总体上还是能满足的,有点意思