蓝牙电话同步完通讯录之后,还需要对联系人进行处理,包括获取首字母索引,中文排序等操作。可能涉及到如下几个需求:
1,查看名字是否含有除数字,汉字,字母以外的其他特殊字符,这里我们最好的办法就是使用正则表达式来判断:
Pattern p3 = Pattern.compile("[^\u4E00-\u9FA5a-zA-Z0-9]");
Matcher m = p3.matcher("asdff汉字ㅇㅎㅇ");
if(m.find()){
System.out.println("find other char");
}else{
System.out.println("available");
}
//结果: find other char
知识点a:其中使用到Matcher.find()方法,它代表只要存在符合表达式的字串,就会匹配成功。
知识点b:表达式 [^\u4E00-\u9FA5a-zA-Z0-9] ,[]中括号代表字符范围,\u4E00-\u9FA5表示中文字符范围,a-zA-Z代表英文字母范围,0-9代表数字范围,而前面的^符号如果是在字符集最开始,表示反向字符集,也就是取反的意思。
2,判断名字是否是以中文汉字或者字母开头
Pattern p6 = Pattern.compile("[\u4E00-\u9FA5a-zA-Z]+");
Matcher m = p6.matcher("@@CCCCasdff汉字**");
if(m.lookingAt()){
System.out.println("match");
}else{
System.out.println("no");
}
m = p6.matcher("CCCCasdff汉字**");
if(m.lookingAt()){
System.out.println("match");
}else{
System.out.println("no");
}
/**
结果:no
match
*/
知识点a:Matcher.lookingAt()尝试从字符开头的位置与表达式模式匹配。
知识点b:+号表示一次或多次匹配前面的字符或子表达式。
3,把联系人按照拼音规则排序,并且可以按照首字母实现快速查找。如果是特殊的名字或者是数字则归入到“#”号序列中。其中#号序列的联系人,有的需求是放在最前面,有的需求是放在最后面,我们这里是放在最后面。部分代码如下:
/**
* 获取每一个联系人名字中的首字母
*/
private void initFirstChar(){
for (ContactItem item : contactItems){
if(TextUtils.isEmpty(item.getName())){
item.setFirstChar('#');
continue;
}
Pattern p = Pattern.compile("[\u4E00-\u9FA5a-zA-Z]+");
Matcher m = p.matcher(item.getName());
if(m.lookingAt()){
//如果是以汉字或字母开头,则获取拼音字符串,然后获取首个字符
String fullpingyin = getPingyin(item.getName());
item.setFirstChar(fullpingyin.toCharArray()[0]);
}else{
//否则直接设置#号
item.setFirstChar('#');
}
}
}
/**
* 获取汉字拼音字符串
* @param inputString
* @return
*/
private String getPingyin(String inputString){
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_V);
char[] input = inputString.trim().toCharArray(); //去掉字符串两端多余的空格
String output = "";
try {
for (int i = 0; i < input.length; i++) {
if (java.lang.Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);
output += temp[0];
} else
output += java.lang.Character.toString(input[i]);
}
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
return output;
}
备注:这里的汉字拼音的处理,需要导入pinyin4j包。
然后就是排序了,这里使用Comparator比较器接口,在实现方法中使用Collator比较中文排序:
class PingyinCompar implements Comparator<ContactItem>{
@Override
public int compare(ContactItem o1, ContactItem o2) {
if(o1.getFirstChar() == '#'){
if(o2.getFirstChar() == '#'){
return 0;
}
return 1;
}else if(o2.getFirstChar() == '#'){
if(o1.getFirstChar() == '#'){
return 0;
}
return -1;
}
//如果开头是英文字母
if((isStartByWord(o1.getName()) && !isStartByWord(o2.getName()))
|| (isStartByWord(o2.getName()) && !isStartByWord(o1.getName()))){
if(o1.getFirstChar() >= o2.getFirstChar()){
return 1;
}else{
return -1;
}
}
Collator collator = Collator.getInstance(Locale.CHINA); //设置中文语言环境
int presult = collator.compare(o1.getName(),o2.getName());
if (presult > 0) {
return 1;
} else if (presult < 0) {
return -1;
} else {
return 0;
}
}
boolean isStartByWord(String name){
Pattern p = Pattern.compile("[a-zA-Z]+");
Matcher m = p.matcher(name);
if(m.find()){
return true;
}else{
return false;
}
}
}
contactItems.add(new ContactItem("联通你我他"));
contactItems.add(new ContactItem("赵四尼古拉斯"));
contactItems.add(new ContactItem("li四haha"));
contactItems.add(new ContactItem("12中国移动"));
contactItems.add(new ContactItem("zhaosi古拉斯"));
contactItems.add(new ContactItem("联通abs"));
contactItems.add(new ContactItem("ㄹㅇㄹㅇㅎ拉斯"));
contactItems.add(new ContactItem("赵飞飞"));
contactItems.add(new ContactItem("7778899"));
contactItems.add(new ContactItem("1234566"));
contactItems.add(new ContactItem("联通&&^%%"));
contactItems.add(new ContactItem("数字123"));
contactItems.add(new ContactItem("ดกดหกดกหก"));
contactItems.add(new ContactItem("泰语ดกดหกดกหก泰语"));
contactItems.add(new ContactItem(""));
PingyinCompar compar = new PingyinCompar();
initFirstChar();
Collections.sort(contactItems,compar);
for (ContactItem item : contactItems){
Log.i("ComparUtil","name:" + item.getName()
+ " ; firstchar:"+String.valueOf(item.getFirstChar()));
}
输出结果:
name:联通&&^%% ; firstchar:l
name:联通你我他 ; firstchar:l
name:联通abs ; firstchar:l
name:数字123 ; firstchar:s
name:泰语ดกดหกดกหก泰语 ; firstchar:t
name:赵飞飞 ; firstchar:z
name:赵四尼古拉斯 ; firstchar:z
name:li四haha ; firstchar:l
name:zhaosi古拉斯 ; firstchar:z
name:12中国移动 ; firstchar:#
name:ㄹㅇㄹㅇㅎ拉斯 ; firstchar:#
name:ㅇㄹㅇㅎ哈韩 ; firstchar:#
name:7778899 ; firstchar:#
name:1234566 ; firstchar:#
name:ดกดหกดกหก泰语 ; firstchar:#
name: ; firstchar:#