提高你的Java代码质量吧:中文字符串排序的瑕疵
来源:互联网 发布:如何开淘宝 编辑:程序博客网 时间:2024/05/22 17:10
一、分析
在Java中一设计中文处理就会冒出很多问题来,其中排序也是一个让人头疼的课题。
我们知道Arrays工具类的默认排序是通过数组元素的compareTo方法来进行比较的,那我们来看String类的compareTo方法的主要实现:
- while(k < lim){
- //原字符串的字符数组
- char c1 = v1[k];
- //比较字符串的字符数组
- char c2 = v2[k];
- if(c1 != c2){
- //比较两者的char值大小
- return c1 - c2;
- }
- k++
- }
while(k < lim){ //原字符串的字符数组 char c1 = v1[k]; //比较字符串的字符数组 char c2 = v2[k]; if(c1 != c2){ //比较两者的char值大小 return c1 - c2; } k++ }
它是先取得字符数组,然后一个一个地比较大小,注意这里是字符比较(减号操作符),也就是UNICODE码值比较。
二、场景
我们看如下代码:
- public static void main(String[] args){
- String[] strs = {"张三(Z)","李四(L)","王五(W)"};
- //排序,默认是升序
- Arrays.sort(strs);
- int i = 0;
- for(String str:strs){
- System.out.println((++i) + "、" + str);
- }
- }
public static void main(String[] args){ String[] strs = {"张三(Z)","李四(L)","王五(W)"}; //排序,默认是升序 Arrays.sort(strs); int i = 0; for(String str:strs){ System.out.println((++i) + "、" + str); } }
结果:
1、张三(Z)
2、李四(L)
3、王五(W)
由上面分析Arrays.sort()使用数组元素的compareTo方法进行比较,它比较字符数组的UNICODE码值,查下UNICODE代码表,"张"的码值是5F20,"李"是674E,这样一看,"张"排在"李"前面也就正确了。
但是这与我们的意图冲突,这一点在JDK文档中也有说明:对于非英文的String排序,可能会出现不正确的情况。
那我们如何解决呢?Java推荐使用Collator类进行排序,代码修改如下:
- public static void main(String[] args)throws Exception{
- String[] strs = {"张三(Z)","李四(L)","王五(W)"};
- //定义一个中文排序器
- Comparator c = Collator.getInstance(Local.CHINA);
- //升序排列
- Arrays.sort(strs,c);
- int i = 0;
- for(String str:strs){
- System.out.println((++i) + "、" + str);
- }
- }
public static void main(String[] args)throws Exception{ String[] strs = {"张三(Z)","李四(L)","王五(W)"}; //定义一个中文排序器 Comparator c = Collator.getInstance(Local.CHINA); //升序排列 Arrays.sort(strs,c); int i = 0; for(String str:strs){ System.out.println((++i) + "、" + str); } }
结果:
1、李四(L)
2、王五(W)
3、张三(Z)
但是注意了,汉字有象行文字,音行分离。不是每个汉字都能按照拼音的顺序排序好的,如"犇"和"鑫"。
三、建议
如果是排序对象是经常使用的汉字,使用Collator类排序完全就可以满足我们的要求。如果需要严格排序,则需要使用一些开源的项目来实现了,比如pinyin4j可以把汉字转换为拼音,然后我们自己来实现排序算法。
- 提高你的Java代码质量吧:中文字符串排序的瑕疵
- Java提高:中文字符串排序的瑕疵
- 提高你的Java代码质量吧
- 提高你的Java代码质量吧:让我们疑惑的字符串拼接方式的选择
- 提高你的Java代码质量吧:推荐在复杂字符串操作中使用正则表达式
- 提高你的Java代码质量吧:推荐在复杂字符串操作中使用正则表达式 .
- 提高你的Java代码质量吧:危险的边界
- 提高你的Java代码质量吧:提倡异常封装
- 如何提高你的代码质量
- 提高你的Java代码质量吧:不同的列表应该选择不同的遍历方法
- 提高你的Java代码质量吧:三元操作符的类型陷阱
- 提高你的Java代码质量吧:不容忽视的四舍五入细节
- 提高你的Java代码质量吧:提防包装类型的null值
- 提高你的Java代码质量吧:不容忽视的四舍五入细节
- 提高你的Java代码质量吧:谨慎包装类型的比较
- 提高你的Java代码质量吧:字符拼接位置的玄机
- 提高你的Java代码质量吧:不容忽视的四舍五入细节
- 提高你的Java代码质量吧:警惕数组的浅拷贝
- Linux tcpdump命令详解
- SAP 内存计算的历史 History of in-memory computing at SAP
- 高效文件操作
- 元芳对SEO优化的重点怎么看
- HIve升级到新版本过程
- 提高你的Java代码质量吧:中文字符串排序的瑕疵
- VirtualBox 虚拟机使用图文教程【系统安装+快照+文件共享+U盘读取】
- Contact 笔记
- Ural 1087. The Time to Take Stones
- DBI接口与DPI接口与DSI接口
- JUNIT+SPRINGMVC的mock测试
- iOS-ASI
- 几个关键字auto register extern简介
- 黑马程序员_02_运算符_进制转换