引入坐标
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
工具类
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.HanyuPinyinVCharType;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
@Component
public class PinyinSearchTrie {
private TrieNode root;
public PinyinSearchTrie() {
this.root = new TrieNode();
}
public void addNamesWithId(Map<String, String> map) throws Exception {
for (Map.Entry<String, String> entry : map.entrySet()) {
String id = entry.getKey();
String name = entry.getValue();
String fullPinyin = getFullPinyin(name);
String firstLetters = getFirstLetters(name);
insert(fullPinyin, id);
insert(firstLetters, id);
}
}
private void insert(String pinyin, String id) {
TrieNode node = root;
for (char c : pinyin.toCharArray()) {
node = node.children.computeIfAbsent(c, k -> new TrieNode());
}
node.isEndOfWord = true;
node.ids.add(id);
}
public List<String> search(String prefix) {
TrieNode node = root;
List<String> results = new ArrayList<>();
for (char c : prefix.toCharArray()) {
node = node.children.get(c);
if (node == null) {
return results;
}
}
collectAllIds(node, results);
return results;
}
private void collectAllIds(TrieNode node, List<String> results) {
if (node.isEndOfWord) {
results.addAll(node.ids);
}
for (char c : node.children.keySet()) {
collectAllIds(node.children.get(c), results);
}
}
private String getFullPinyin(String chinese) throws Exception {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_V);
StringBuilder pinyin = new StringBuilder();
for (char c : chinese.toCharArray()) {
if (Character.toString(c).matches("[\\u4E00-\\u9FA5]")) {
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyinArray != null) {
pinyin.append(pinyinArray[0]);
}
} else {
pinyin.append(c);
}
}
return pinyin.toString();
}
private String getFirstLetters(String chinese) throws Exception {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_V);
StringBuilder firstLetters = new StringBuilder();
for (char c : chinese.toCharArray()) {
if (Character.toString(c).matches("[\\u4E00-\\u9FA5]")) {
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyinArray != null) {
firstLetters.append(pinyinArray[0].charAt(0));
}
} else {
firstLetters.append(c);
}
}
return firstLetters.toString();
}
private static class TrieNode {
Map<Character, TrieNode> children = new HashMap<>();
List<String> ids = new ArrayList<>();
boolean isEndOfWord = false;
}
public static void main(String[] args) throws Exception {
PinyinSearchTrie searchTrie = new PinyinSearchTrie();
Map<String, String> map = new HashMap<>();
map.put("001", "北京");
map.put("002", "上海");
map.put("003", "广州");
map.put("004", "深圳");
map.put("005", "杭州市");
map.put("006", "成都");
map.put("007", "重庆");
map.put("008", "武汉");
searchTrie.addNamesWithId(map);
String query1 = "du";
String query2 = "sh";
String query3 = "cheng";
List<String> result1 = searchTrie.search(query1);
List<String> result2 = searchTrie.search(query2);
List<String> result3 = searchTrie.search(query3);
System.out.println("搜索 'du' 的ID结果: " + result1);
System.out.println("搜索 'sh' 的ID结果: " + result2);
System.out.println("搜索 'cheng' 的ID结果: " + result3);
}
}
调用示例
Map<String, String> map = list.stream().filter(p -> StrUtil.isNotBlank(p.getPersonName())).collect(Collectors.toMap(PeopleInformationBase::getId, PeopleInformationBase::getPersonName));
pinyinSearchTrie.addNamesWithId(map);
List<String> ids = pinyinSearchTrie.search(form.getPersonName());