拼音排序
拼音有好几种方式,其中最主要的是中华人民共和国的汉语拼音 Chinese Phonetic。对汉字的排序有两种:一种是宽松的,能够按拼音排序最常用的汉字,另一种是严格的,能够按拼音排序绝大部分大部分汉字。
宽松的拼音排序法
原理:汉字最早是GB2312编码,收录了六千多个汉字,是按拼音排序的,编码是连续的。 后来出现了GBK编码,对GB2312进行了扩展,到了两万多汉字,并且兼容GB2312,也就是说GB2312中的汉字编码是原封不动搬到GBK中的(在GBK编码中[B0-D7]区中)。
如果我们只关心这6000多个汉字的顺序,就可以用下面的方法实现汉字宽松排序。
package com.zhaosoft.chinese.utility;
import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
/**
* @author zhaosoft
*/
public class PinyinSimpleComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return Collator.getInstance(Locale.CHINESE).compare(o1, o2);
}
public static void main(String[] args) {
String[] data = { "孙", "孟", "宋", "尹", "廖", "张", "徐", "昆","曹", "曾", "怡" };
List<String> list = Arrays.asList(data);
Arrays.sort(data, new PinyinSimpleComparator());
System.out.println(list);
}
}
在对[孙, 孟, 宋, 尹, 廖, 张, 徐, 昆, 曹, 曾,怡]这几个汉字排序,结果是:[曹, 昆, 廖, 孟, 宋, 孙, 徐, 尹, 曾, 张, 怡]。最后一个 怡 有问题,不该排在最后的。
注意:这个程序有两个不足
由于gb2312中的汉字编码是连续的,因此新增加的汉字不可能再按照拼音顺序插入到已有的gb2312编码中,所以新增加的汉字不是按拼音顺序排的。
同音字比较的结果不等于0 。
下面的测试代码可以证明
/**
* 非常用字(怡)
*/
@Test
public void testNoneCommon() {
Assert.assertTrue(comparator.compare("怡", "张") > 0);
}
/**
* 同音字
*/
@Test
public void testSameSound() {
Assert.assertTrue(comparator.compare("怕", "帕") != 0);
}
严格的拼音排序法
为了解决宽松的拼音的两点不足,可以通过实现汉语拼音的函数来解决。goolge下看到sf上有个pinyin4j的项目,可以解决这个问题,pinyin4j的项目地址是:http://pinyin4j.sourceforge.net/。
实现代码:
package com.zhaosoft.chinese.utility;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import net.sourceforge.pinyin4j.PinyinHelper;
/**
* @author zhaosoft
*/
public class PinyinComparator implements Comparator<String> {
private String concatPinyinStringArray(String[] pinyinArray) {
StringBuffer pinyinStrBuf = new StringBuffer();
if ((null != pinyinArray) && (pinyinArray.length > 0)) {
for (int i = 0; i < pinyinArray.length; i++) {
pinyinStrBuf.append(pinyinArray[i]);
}
}
String outputString = pinyinStrBuf.toString();
return outputString;
}
@Override
public int compare(String o1, String o2) {
char c1 = ((String) o1).charAt(0);
char c2 = ((String) o2).charAt(0);
return concatPinyinStringArray(
PinyinHelper.toHanyuPinyinStringArray(c1)).compareTo(
concatPinyinStringArray(PinyinHelper
.toHanyuPinyinStringArray(c2)));
}
public static void main(String[] args) {
String[] data = { "孙", "孟", "宋", "尹", "廖", "张", "张", "张", "徐", "昆","曹", "曾", "怡" };
List<String> list = Arrays.asList(data);
Arrays.sort(data, new PinyinComparator());
System.out.println(list);
}
}
输出结果:
[曹, 曾, 昆, 廖, 孟, 宋, 孙, 徐, 怡, 尹, 张, 张, 张]