废话不多说,上问题
如果你需要根据数据库的某个字段的首字母,按拼音顺序排序分组发给前端,那就找对了。
上代码
1.由于字段内容,有英文或者中文开头,直接排序不了,需要把中文变成拼音才能继续操作。
<!-- 导入依赖 -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>
2.编写代码
// 获取字符串的拼音字母
private static String getPinyin(String input) {
StringBuilder output = new StringBuilder();
char[] chars = input.toCharArray();
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
for (char c : chars) {
if (Character.isLetter(c)) { // 判断字符是否为字母
output.append(Character.toLowerCase(c));
} else if (isChinese(c)) { // 判断字符是否为中文
String[] pinyinArray = new String[0];
try {
pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
if (pinyinArray == null) {
output.append(c);
} else {
output.append(pinyinArray[0].charAt(0));
}
}
}
return output.toString();
}
/**
* @param key 按这个字段拼音,排序分组
* @param arrayMap {@link List}<{@link HashMap}<{@link String}, {@link Object}>>
* @return {@link Map}<{@link String}, {@link List}<{@link HashMap}<{@link String}, {@link Object}>>>
* @apiNote 按拼音顺序排列分组,字符串的第一个文字无论是中文还是英文,不影响排序结果,<p>应用场景: </p><p>通讯录,好友列表,A-Z。</p>
* @since 2023-10-17
**/
private static Map<String, List<HashMap<String, Object>>> GroupedInPinyinOrder(ArrayList<HashMap<String, Object>> arrayMap, String key) {
// 创建自定义的Comparator
Comparator<HashMap<String, Object>> comparator = (hashMap, hashMap2) -> {
String name = (String) hashMap.get(key);
String name2 = (String) hashMap2.get(key);
// 比较首字母或拼音
String pinyin = getPinyin(name);
String pinyin2 = getPinyin(name2);
return pinyin.compareTo(pinyin2);
};
//按拼音顺序排序A-Z
arrayMap.sort(comparator);
//按拼音顺序分组A-Z
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
Map<String, List<HashMap<String, Object>>> groupedData = new TreeMap<>();
for (HashMap<String, Object> data : arrayMap) {
String name = (String) data.get(key);
//作为groupedData的key
String pinyin = String.valueOf(getPinyin(name).charAt(0)).toUpperCase();
char c = pinyin.toLowerCase().toCharArray()[0];
try {
//如果首字符为中文,则转换成拼音取首字母
if (isChinese(c)) {
pinyin = String.valueOf(PinyinHelper.toHanyuPinyinStringArray(c, format)[0].toUpperCase().charAt(0));
}
} catch (Exception e) {
e.printStackTrace();
}
List<HashMap<String, Object>> group = groupedData.computeIfAbsent(pinyin, k -> new ArrayList<>());
group.add(data);
}
return groupedData;
}
private static boolean isChinese(char c) {
Character.UnicodeBlock block = Character.UnicodeBlock.of(c);
return block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS ||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS ||
block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||
block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B ||
block == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION ||
block == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS ||
block == Character.UnicodeBlock.GENERAL_PUNCTUATION;
}
3.测试数据
ArrayList<HashMap<String, Object>> arrayMap = new ArrayList<>();
list.forEach((elem -> {
HashMap<String, Object> hashMap = new HashMap<>();
User user = userService.getById(elem.getUserId());
hashMap.put("id", elem.getToId());
hashMap.put("avatar", user.getAvatar());
hashMap.put("name", elem.getToNotes());
arrayMap.add(hashMap);
}));
4.测试与结果
System.out.println(GroupedInPinyinOrder(arrayMap, "name").toString());
5.总结
如果直接用数据库查出来,不用Map,可用实体对象,其思路是一致的,稍微改一下即可,如果对你有用,欢迎一键三联。