前几天,朋友的项目中要用到中英文混合排序的功能,和我在MSN上讨论实现方法.
恰逢端午节放假,我闲来无事,就把解决方法捣鼓出来了,希望能派上用场.
这是完整代码的下载地址:
http://download.csdn.net/source/1362450
一共有三个类:PinyinComparator的作用是实现Comparator接口,PingYinUtil的作用是将汉字转化为拼音.Test是测试类,用于观看演示实际效果.
这是目录结构:
1.先看用作演示的Test类,这个类仅供测试用.
package pinyin;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
publicvoidsort() {
// 数组排序
String[] array = {"xyz中abc-中国","xyz中abc-美国"}
;
List list1 =Arrays.asList(array);
Arrays.sort(array,newPinyinComparator());
System.out.println(list1);
// 集合排序
List list2 =newArrayList();
list2.add("张一");
list2.add("张二");
Collections.sort(list2,newPinyinComparator());
System.out.println(list2);
}
public staticvoidmain(String[] args) {
newTest().sort();
}
}
在这里,Arrays.sort()实现了对数组的排序,Collections.sort()实现了对集合的排序.
在实际应用中,用得更多的可能是对集合的排序.
运行结果如下:
中国与美国相比,前面那一串("xyz中abc-")都一样,都是带把儿的,但m在z前面,所以中国和美国还有些差距.
"张一"的全拼是"zhangyi","张二"是"zhanger",e在y的前面,所以张二排在前面.
论大小,老大比老二牛;但要"拼淫",老二却排在老大的前面.
2.PinyinComparator,这个是具体实现比较的类,他比较的是汉语拼音,而不是汉字.
package pinyin;import java.util.Comparator;
/**
*拼音比较器
*
* @author 龚刚
*
*/
public class PinyinComparator implementsComparator<
Object>
{
publicintcompare(Object o1,Object o2) {
String str1 = PingYinUtil.getPingYin((String) o1);
String str2 = PingYinUtil.getPingYin((String) o2);
return str1.compareTo(str2);
}
}
修改这个类,就可以实现其他的排序算法.比如按笔画排序.
不过还是按拼音排序用得广泛.
只有某些官样文章,或几百万个专家合作编著的十几页的小册子,才按笔画排序.
3.PingYinUtil,这个类中采用了开源组件pinyin4j.
pinyin4j的官网,在sourceforge上:
http://pinyin4j.sourceforge.net
话说浙江大学的牛人还真多啊,前不久用的什么linux下的多线程下载工具(虽然用着不满意),好像也是浙大的开发的.
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.*;
/**
* 拼音工具类
*
* @author 龚刚
*/
public class PingYinUtil {
/**
* 将字符串中的中文转化为拼音,其他字符不变
*
* @param inputString
* @return
*/
public staticStringgetPingYin(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;
}
}
解释一下代码:
(1).HanyuPinyinOutputFormat,定义汉语拼音的输出形式.
(2).HanyuPinyinCaseType,定义汉语拼音的大小写,如:
LOWERCASE min2
UPPERCASE MIN2
(3).HanyuPinyinToneType,定义音调的显示方式.如:
WITH_TONE_MARK dǎ ,带音调
WITH_TONE_NUMBER da3 ,带音调,用12345表示平上去入和轻声
WITHOUT_TONE da ,不带音调
(4).HanyuPinyinVCharType,定义'ü' 的显示方式.如:
WITH_U_AND_COLON u: ,u加两点表示,如律师表示为lu:shi
WITH_V v ,用字母v表示,这个用搜狗输入法的人想必有些印象.
WITH_U_UNICODE ü
(5).input[i]).matches("[\\u4E00-\\u9FA5]+"),这个用来判断是否为中文的.
(6).PinyinHelper.toHanyuPinyinStringArray(input[i], format),这个返回单字的拼音字符串数组.
如果音调类型为WITH_TONE_NUMBER的话,"张",将返回"zhang1","李",会返回"li4".
http://javafun.yo2.cn/pinyin4j.html