一、需求分析
最近在做一个类似于微信用户通讯录的功能,所以考虑通过查找的好友列表,在后台遍历按照26个字母分组,前台获取到Json循环26个字母直接解析对应的字符下的名称为一组分隔,没有则不显示,工具如下↓
二、引入Pom
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>
三、代码工具
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ev.viewworld.model.sysuser;
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 net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class changeChinesePinyinUtil {
/**
* 获取姓名全拼和首字母
* @author 于公成
* @param chinese 汉语名称
* @return fullPinyin : 全拼 simplePinyin : 首字母 groupPinyin:微信用户组第一个字母
* @throws BadHanyuPinyinOutputFormatCombination
*/
public static Map<String, String> changeChinesePinyin(String chinese) throws BadHanyuPinyinOutputFormatCombination {
Map<String, String> pinyin = new HashMap<String, String>();
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_V);
StringBuffer fullPinyin = new StringBuffer();
StringBuffer simplePinyin = new StringBuffer();
StringBuffer firstPinyin = new StringBuffer();
char[] chineseChar = chinese.toCharArray();
for (int i = 0; i < chineseChar.length; i++) {
String[] str = null;
try {
str = PinyinHelper.toHanyuPinyinStringArray(chineseChar[i],
format);
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
if (str != null) {
fullPinyin = fullPinyin.append(str[0].toString());
simplePinyin = simplePinyin.append(str[0].charAt(0));
}
if (str == null) {
String regex = "^[0-9]*[a-zA-Z]*+$";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(String.valueOf(chineseChar[i]));
if (m.find()) {
fullPinyin = fullPinyin.append(chineseChar[i]);
simplePinyin = simplePinyin.append(chineseChar[i]);
}
}
}
String[] name = PinyinHelper.toHanyuPinyinStringArray(chineseChar[0],format);
firstPinyin=firstPinyin.append(name[0].charAt(0));
pinyin.put("fullPinyin", fullPinyin.toString());
pinyin.put("simplePinyin", simplePinyin.toString().toUpperCase());
pinyin.put("groupPinyin", firstPinyin.toString().toUpperCase());
return pinyin;
}
/**
* 按拼音首字母分组
* @author 于公成
* @param list
* @return
* @throws BadHanyuPinyinOutputFormatCombination
*/
public static Map<String, Object> getCodeGroup(List<String> list) throws BadHanyuPinyinOutputFormatCombination {
Comparator<Object> com = Collator.getInstance(java.util.Locale.CHINA);
//按字母排序
Collections.sort(list, com);
//输出26个字母
Map<String, Object> map = new TreeMap<String, Object>();
for(int i=1;i<=26;i++){
String word = String. valueOf((char) (96 + i)). toUpperCase();
//循环找出首字母一样的数据
List<String> letter = new ArrayList<String>();
for (String str : list) {
String code=changeChinesePinyin(str).get("groupPinyin");
if(word.equals(code)) {
letter.add(str);
}
System.out.println(str);
}
map.put(word, letter);
}
System.out.println(map);
return map;
}
/**
* @author 于公成
* 按用户拼音首字母分组
* @param list
* @return
* @throws BadHanyuPinyinOutputFormatCombination
*/
public static Map<String, List<sysuser>> getUserCodeGroup(List<sysuser> list) throws BadHanyuPinyinOutputFormatCombination {
//Collections工具类的sort()方法对list集合元素排序
Collections.sort(list,new Comparator<sysuser>(){
@Override
public int compare(sysuser o1, sysuser o2) {
//获取中文环境
Comparator<Object> com = Collator.getInstance(java.util.Locale.CHINA);
return com.compare(o1.getRealname(),o2.getRealname());
}
});
//输出26个字母
Map<String, List<sysuser>> map = new TreeMap<String, List<sysuser>>();
for(int i=1;i<=26;i++){
String word = String. valueOf((char) (96 + i)). toUpperCase();
//循环找出首字母一样的数据
List<sysuser> letter = new ArrayList<sysuser>();
for (sysuser str : list) {
String code=changeChinesePinyin(str.getRealname()).get("groupPinyin");
if(word.equals(code)) {
letter.add(str);
}
System.out.println(str);
}
map.put(word, letter);
}
System.out.println(map);
return map;
}
public static void main(String[] args) throws BadHanyuPinyinOutputFormatCombination {
// System.out.println(changeChinesePinyin("于公成").get("groupPinyin"));
List<String> list=new ArrayList<String>();
list.add("于公成");
list.add("由于工程");
list.add("与工程");
list.add("王为");
list.add("刘汝祥");
list.add("阿宝");
list.add("阿亮");
getCodeGroup(list);
}
}
三、最终结果
四、附加备注
这个只是中文排序, 如果按照微信的去做, 排序先判断类型
- 中文(如果是中文名称按照26个字母排序)
- 英文(获取首字母排序)
- 不确定符号/空格/表情/数字...(不排序放到通讯录最后,可以参考微信#)
中英文验证代码
public static boolean isChinese(String con) {
for (int i = 0; i < con.length(); i = i + 1) {
if (!Pattern.compile("[\u4e00-\u9fa5]").matcher(
String.valueOf(con.charAt(i))).find()) {
return false;
}
}
return true;
}
private static boolean isEnglish(String con) {
if (null != con && !"".equals(con)) {
if ((isChinese(con) || con.matches("^[A-Za-z]+$"))) {
return true;
}
}
return false;
}