java拼音排序 彻底解决将汉字转化为拼音 实现中英文混合排序 pinyin4j(转)



前几天,朋友的项目中要用到中英文混合排序的功能,和我在MSN上讨论实现方法.
恰逢端午节放假,我闲来无事,就把解决方法捣鼓出来了,希望能派上用场.

这是完整代码的下载地址:

一共有三个类:PinyinComparator的作用是实现Comparator接口,PingYinUtil的作用是将汉字转化为拼音.Test是测试类,用于观看演示实际效果.
这是目录结构:

java中中文排序的方法 java汉字按拼音排序_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()实现了对集合的排序.
在实际应用中,用得更多的可能是对集合的排序.
运行结果如下:

java中中文排序的方法 java汉字按拼音排序_bc_02

中国与美国相比,前面那一串("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上:话说浙江大学的牛人还真多啊,前不久用的什么linux下的多线程下载工具(虽然用着不满意),好像也是浙大的开发的.

package pinyin; 
  
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".