Java中文字符按Unicode排序的实现方法

  

遇到了一个对包含中文的字符串进行排序的问题。要求按unicode编码对字符串进行排序。

  

测试字符串数组如下:

        String [] arr={   “1 -测试”,   “1 -编辑”,   “1 -营销”,   “1结束”,   “2 -测试”,   “1-qt”   };      

按unicode排序的期望结果应该是这样的:

  
  

1 -编辑,1 -测试,1 -营销,1-qt, 1结束,2 -测试
  

     

先按以类提供的默认比较方案进行实现,大致如下:

        进口java.util.Arrays;   进口java.util.Comparator;   公开课MyJob {   公共静态void main (String [] args) {   String [] arr={   “1 -测试”,   “1 -编辑”,   “1 -营销”,   “1结束”,   “2 -测试”,   “1-qt”   };   Comparatorc=字符串:compareTo;   数组。排序(arr c);   System.out.println (Arrays.toString (arr));   }   }      

结果如下:

  
  

[1-qt, 1 -测试,1 -编辑,1 -营销,1结束,2 -测试]
  

     

可以看到中文字符不能按照拼音进行排序。这时最直接的思路就是将中文字符转为拼音后再进行排序。但是要注意下,在这里面有个字符串不包含中文字符,这就容易导致顺序混乱。

  

如下面这几个字符串按拼音进行排序顺序如下:

  
  

1 -编辑,1 -测试,1-qt, 1 -营销
  

     

可以看到字符串“1-qt”的位置出错了。但是按拼音来说它的位置又是对的。这不能不说是一个让人有些头疼的地方。

  

不过不用担心,java提供了java.text.Collator类来支持规范化的字符串比较。

  

使用排序器来改造之前的代码:

        进口java.text.Collator;   进口java.util.Arrays;   进口java.util.Comparator;   进口java.util.Locale;   公开课MyJob {   公共静态void main (String [] args) {   String [] arr={   “1 -测试”,   “1 -编辑”,   “1 -营销”,   “1结束”,   “2 -测试”,   “1-qt”   };   Comparatorc=(o1、o2)→Collator.getInstance (Locale.CHINESE) .compare (o1、o2);   数组。排序(arr c);   System.out.println (Arrays.toString (arr));   }   }      

改造后的程序执行排序的结果如下:

  
  

[1-qt, 1 -编辑,1 -测试,1结束,1 -营销,2 -测试]
  

     

结果看着好像还好。但是停,停注意下,字符串“1结束”的位置好像比较奇妙,理想情况下它应该在“1 -营销”的后面。

  

这里出问题的原因我没有弄清楚。猜测着应该是java在中国语法中将中划线处理为空字符了。不过最根本的问题还是java对Unicode排序算法(UCA, Unicode整理算法)的支持并不好。

  

此时可以考虑使用IBM ICU提供的排序器来替换jdk默认的排序器。代码如下:

        进口com.ibm.icu.text.Collator;   进口java.util.Arrays;   进口java.util.Comparator;   进口java.util.Locale;   公开课MyJob {   公共静态void main (String [] args) {   String [] arr={   “1 -测试”,   “1 -编辑”,   “1 -营销”,   “1结束”,   “2 -测试”,   “1-qt”   };   Comparatorc=(o1、o2)→Collator.getInstance (Locale.CHINESE) .compare (o1、o2);   数组。排序(arr c);   System.out.println (Arrays.toString (arr));   }   }      

相关的依赖为:

        & lt; dependency>   & lt; groupId> com.ibm.icu   & lt; artifactId> icu4j-localespi   & lt; version> 60.2 & lt;/version>   & lt;/dependency>      

执行结果为:

  
  

[1 -编辑,1 -测试,1 -营销,1-qt, 1结束,2 -测试)

     

可以看到是和预期一致的。

  

总结   

Java中文字符按Unicode排序的实现方法