Skip to content

Commit

Permalink
支持不同的第三方拼音库
Browse files Browse the repository at this point in the history
  • Loading branch information
yindz committed Aug 6, 2022
1 parent a9f0f17 commit 3f8766f
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 7 deletions.
57 changes: 57 additions & 0 deletions src/main/java/com/apifan/common/random/util/PinyinUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.apifan.common.random.util;

import com.apifan.common.random.util.pinyin.PinyinConverter;
import com.apifan.common.random.util.pinyin.impl.Pinyin4jConverter;
import com.apifan.common.random.util.pinyin.impl.TinyPinyinConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 拼音工具类
* <p>
* 从 1.0.16 起,不再强依赖 tinypinyin; <br>
* 支持目前常用的以下2种第三方库: tinypinyin/pinyin4j <br>
* 检测顺序:tinypinyin>pinyin4j <br>
* 注意: 不要忘记手动添加依赖
* </p>
*
* @author yin
* @since 1.0.16
*/
public class PinyinUtils {
private static final Logger log = LoggerFactory.getLogger(PinyinUtils.class);

private static final PinyinConverter pinyinConverter;

static {
pinyinConverter = getRealPinyinConverter();
}

/**
* 转换成拼音
*
* @param src 原始字符串
* @param toLowerCase 是否转换为小写
* @return 拼音
*/
public static String toPinyin(String src, boolean toLowerCase) {
return pinyinConverter.toPinyin(src, toLowerCase);
}

/**
* 获取拼音转换器实例
*
* @return 拼音转换器实例
*/
private static PinyinConverter getRealPinyinConverter() {
if (ResourceUtils.isClassLoaded("com.github.promeg.pinyinhelper.Pinyin")) {
log.info("将使用 tinypinyin");
return new TinyPinyinConverter();
} else if (ResourceUtils.isClassLoaded("net.sourceforge.pinyin4j.PinyinHelper")) {
log.info("将使用 pinyin4j");
return new Pinyin4jConverter();
} else {
throw new RuntimeException("没有找到可用的拼音库");
}
}
}
29 changes: 22 additions & 7 deletions src/main/java/com/apifan/common/random/util/ResourceUtils.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.apifan.common.random.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
Expand Down Expand Up @@ -62,11 +60,9 @@ public static String readString(String fileName) {
*/
public static List<Map<String, Object>> readAsMapList(String fileName) {
Preconditions.checkArgument(StringUtils.isNotEmpty(fileName), "资源文件名为空");
ObjectMapper objectMapper = new ObjectMapper();
try {
CollectionType collectionType = objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class);
return objectMapper.readValue(readString(fileName), collectionType);
} catch (IOException e) {
return JsonUtils.parseMapList(readString(fileName));
} catch (Exception e) {
logger.error("解析json出现异常", e);
}
return null;
Expand All @@ -83,7 +79,7 @@ public static <T> T getRandomElement(List<T> elementList) {
List<T> randomElement = getRandomElement(elementList, 1);
return randomElement.isEmpty() ? null : randomElement.get(0);
}

/**
* 从列表中获取number个随机元素
*
Expand Down Expand Up @@ -160,4 +156,23 @@ public static List<String> base64DecodeLines(List<String> lines) {
});
return decoded;
}

/**
* 判断当前运行环境下是否存在某个类
*
* @param clazzName 类名
* @return
*/
public static boolean isClassLoaded(String clazzName) {
if (StringUtils.isBlank(clazzName)) {
return false;
}
try {
Class.forName(clazzName);
return true;
} catch (ClassNotFoundException e) {
logger.warn("未找到类: {}", clazzName);
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.apifan.common.random.util.pinyin;

/**
* 拼音转换器接口
*
* @author yin
* @since 1.0.16
*/
public interface PinyinConverter {

/**
* 转换成拼音
*
* @param src 原始字符串
* @param toLowerCase 是否转换为小写
* @return 拼音
*/
String toPinyin(String src, boolean toLowerCase);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.apifan.common.random.util.pinyin.impl;

import com.apifan.common.random.util.pinyin.PinyinConverter;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
* Pinyin4j转换器接口实现类
*
* @author yin
* @since 1.0.16
*/
public class Pinyin4jConverter implements PinyinConverter {
private static final Logger log = LoggerFactory.getLogger(Pinyin4jConverter.class);

/**
* 转换成拼音
*
* @param src 原始字符串
* @param toLowerCase 是否转换为小写
* @return 拼音
*/
@Override
public String toPinyin(String src, boolean toLowerCase) {
Preconditions.checkArgument(StringUtils.isNotBlank(src), "原始字符串为空");
HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
if (toLowerCase) {
outputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
} else {
outputFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
}
List<String> out = new ArrayList<>();
char[] chars = src.toCharArray();
for (char c : chars) {
try {
String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c, outputFormat);
if (pinyin.length > 0) {
//即使是多音字,也只取第1个读音
out.add(pinyin[0]);
}
} catch (BadHanyuPinyinOutputFormatCombination e) {
log.error("转换拼音异常", e);
}
}
return Joiner.on("").join(out);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.apifan.common.random.util.pinyin.impl;

import com.apifan.common.random.util.pinyin.PinyinConverter;
import com.github.promeg.pinyinhelper.Pinyin;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;

/**
* TinyPinyin转换器接口实现类
*
* @author yin
* @since 1.0.16
*/
public class TinyPinyinConverter implements PinyinConverter {

/**
* 转换成拼音
*
* @param src 原始字符串
* @param toLowerCase 是否转换为小写
* @return 拼音
*/
@Override
public String toPinyin(String src, boolean toLowerCase) {
Preconditions.checkArgument(StringUtils.isNotBlank(src), "原始字符串为空");
String result = Pinyin.toPinyin(src, "");
return toLowerCase ? result.toLowerCase() : result;
}
}

0 comments on commit 3f8766f

Please sign in to comment.