开发中碰到个小需求:需要对省按拼音排序。其实全国的省个数并不多,实在不行人肉排序也OK,不过这样就太挫了。
网上查了下,发现原生JDK自带的解决方法如下:
package com.taobao.test;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
public class TestSortChinese {
public static void main(String[] args){
Iterator it = SortChinese.provinceMap.entrySet().iterator();//这里的map里数据是全国所有的省中文String
ArrayList al = new ArrayList();
while(it.hasNext()){
al.add((String)((Map.Entry)(it.next())).getValue());
}
Object[] arr = al.toArray();
Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);
Arrays.sort(arr, cmp);
for(Object s : arr){
System.out.println(s);
}
}
}
打印出来的结果还行,除了重庆因为多音字的原因,被当成了zhong庆排在了末尾,其它的都对了。对于这个特殊情况就单独处理下好了。
这个JDK自带的方法这么好用吗?查证了下发现是有缺陷的,其只能对于GB2312里的中文字符进行正确排序,通俗点说就是只能对常用字好用。但是这个常用字的定义也不能让人很满意,只支持6000多个常用字,这是远远不够的。GBK是GB2312的超集,里面包含了20000多个中文字符(基本就包括所有中文字符了),但是不包含在GB2312里的字符都无法正确排序了。
网上普遍的解决方案是用到一个开源项目:http://pinyin4j.sourceforge.net/。具体可见下面这四篇文章,里面叙述的都比较详细了:
http://www.blogjava.net/spinage/archive/2009/10/15/298403.html
http://hi.baidu.com/chssheng2007/item/1bf3a6dedea5eff492a974fb
http://blog.csdn.net/kennylee26/article/details/3926168
http://blog.csdn.net/machozhao/article/details/1047333
由于此次只用到了点皮毛,所以没有深入的去钻研,但正如参考文章里写到的,实现的原理就是把汉字转化为拼音,然后再进行的排序。有兴趣的读者可以深挖下怎么把汉字转化为拼音。我看到有文章介绍说可以用到系统里的字库的,但未进行实践尝试,暂先不过多叙述了。