pinyin4j项目  官网地址 http://pinyin4j.sourceforge.net/

我们先把资源下载下来,连同源码和jar包一起放入工程。如下图:

接下来在demo包下,我们写一个测试类,简单使用pinyin4j对中文字符进行自然排序

新建一个ConvertTest.java

  1. package demo;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.Comparator;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8.  
  9. import net.sourceforge.pinyin4j.PinyinHelper;
  10.  
  11. public class ConvertTest {
  12.  
  13. public static void main(String[] args) {
  14. String src = "我们中间出了一个叛徒";
  15. char[] arr = src.toCharArray();
  16. System.out.println("数组长度是:"+arr.length);
  17. System.out.print("原始顺序:");
  18. for (char temp : arr) {
  19. System.out.print(temp+" ");
  20. }
  21. System.out.println();
  22. convertToHanyuPinyin(arr);
  23. }
  24.  
  25. private static List<String> convertToHanyuPinyin(char[] array){
  26. HashMap<String, String> map = new HashMap<String, String>();
  27. for (int i = 0; i < array.length; i++) {
  28. //得到拼音首字母
  29. String value = (PinyinHelper.toHanyuPinyinStringArray(array[i]))[0].substring(0, 1);
  30. map.put(String.valueOf(array[i]), value);
  31. }
  32. System.out.println(map);
  33. List<String> list = sort(map);
  34. return list;
  35. }
  36.  
  37. private static List<String> sort(Map map){
  38. List<Map.Entry<String, String>> infoIds =
  39. new ArrayList<Map.Entry<String, String>>(map.entrySet());
  40. // 对HashMap中的 value 进行排序
  41. Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
  42. @Override
  43. public int compare(Map.Entry<String, String> o1,
  44. Map.Entry<String, String> o2) {
  45. return (o1.getValue()).compareTo(o2.getValue());
  46. }
  47. });
  48.  
  49. List<String> list = new ArrayList<String>();
  50. /*****************FOR TEST***********************/
  51. List<String> letterList = new ArrayList<String>();
  52. /*****************FOR TEST***********************/
  53. // 对HashMap中的 value 进行排序后 显示排序结果
  54. for (int i = 0; i < infoIds.size(); i++) {
  55. Map.Entry<String,String> entry = infoIds.get(i);
  56. list.add(entry.getKey());
  57. letterList.add(entry.getValue());
  58. }
  59.  
  60. /*****************FOR TEST***********************/
  61. System.out.print("自然顺序:");
  62. for (String string : list) {
  63. System.out.print(string + " ");
  64. }
  65.  
  66. System.out.println();
  67.  
  68. System.out.print("字母顺序:");
  69. for (String string : letterList) {
  70. System.out.print(string +" ");
  71. }
  72. /*****************FOR TEST***********************/
  73. return list;
  74. }
  75. }

输出结果为:

可以看到最终的输出顺序已经是按照自然顺序排序后的结果了。

简单说一下步骤:

1.我们先将字符串序列转换成 单个字符key, 首字母value  的map形式,

如 {个=g, 徒=t, 我=w, 出=c, 叛=p, 了=l, 中=z, 一=y, 间=j, 们=m}。

2. 然后针对map中的value进行排序,并返回排序过后的key值。

(PS:当然这里也可以对key值进行排序,但是最好还是针对value。

因为我们这里截取的是首字母,并不是整个拼音音节。)

代码缺点:

1.只是针对中文字符的第一个拼音进行排序,但是汉语中存在多音字。

2.只是针对字符的首字母进行排序,并不是整个拼音字节,并不严谨,适合粗略排序的场景。

下面简单分析一下,pinyin4j的转换流程。

如上图,其中核心的类就是PinyinHelper。它可以转换许多类型的拼音,这里我们只看汉语拼音,其他的与之类似。

追踪代码 PinyinHelper.toHanyuPinyinStringArray

按ctrl + 鼠标左键。

  1. static public String[] toHanyuPinyinStringArray(char ch)
  2. {
  3. return getUnformattedHanyuPinyinStringArray(ch);
  4. }

继续跟踪代码

  1. private static String[] getUnformattedHanyuPinyinStringArray(char ch)
  2. {
  3. return ChineseToPinyinResource.getInstance().getHanyuPinyinStringArray(ch);
  4. }

调用ChineseToPinyinResource示例的getHanyuPinyinStringArray方法

  1. String[] getHanyuPinyinStringArray(char ch)
  2. {
  3. String pinyinRecord = getHanyuPinyinRecordFromChar(ch);
  4.  
  5. if (null != pinyinRecord)
  6. {
           //得到左括号( 的索引值
  7. int indexOfLeftBracket = pinyinRecord.indexOf(Field.LEFT_BRACKET);
          //得到右括号) 的索引值
  8. int indexOfRightBracket = pinyinRecord.lastIndexOf(Field.RIGHT_BRACKET);
  9. //得到字符对应的拼音
  10. String stripedString = pinyinRecord.substring(indexOfLeftBracket
  11. + Field.LEFT_BRACKET.length(), indexOfRightBracket);
  12. //以逗号.为分隔 返回String[] 数组
  13. return stripedString.split(Field.COMMA);
  14.  
  15. } else
  16. return null; // no record found or mal-formatted record
  17. }

关键的方法getHanyuPinyinRecordFromChar

  1. private String getHanyuPinyinRecordFromChar(char ch)
  2. {
  3. int codePointOfChar = ch;
  4. //转换成unicode对应的字符
  5. String codepointHexStr = Integer.toHexString(codePointOfChar).toUpperCase();
  6. //从表中查询字符
  7. // fetch from hashtable
  8. String foundRecord = getUnicodeToHanyuPinyinTable().getProperty(codepointHexStr);
  9. //如果是合法的字符就返回,否则返回null
  10. return isValidRecord(foundRecord) ? foundRecord : null;
  11. }

就是如下图的资源:

http://www.cnblogs.com/sphere/p/4738888.html

浅析pinyin4j源码 简单利用pinyin4j对中文字符进行自然排序(转)的更多相关文章

  1. 【转】Android 源码下利用jni编译自己的项目(参考系统development/samples/SimpleJNI)

    原文网址:http://blog.csdn.net/qiuxiaolong007/article/details/7860481 记于正文前:环境是ubuntu10.10,android 源码是2.0 ...

  2. negroni-gzip源码简单分析解读

    negroni-gzip源码简单分析解读 这是一个为Negroni设计的gzip压缩处理中间件,需要用到已有的compress中的gzip,阅读了不长的源码之后,总结了一些关键要点和注意点. 检查是否 ...

  3. FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  4. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  5. APIView源码简单分析图

    APIView源码简单分析 !声明:下面这个dispatch分发方法不在是父类View里的dispatch了,APIView重新封装了这个dispatch.(整个核心就是initialize_requ ...

  6. Django-session中间件源码简单分析

    Django-session中间件源码简单分析 settings里有关中间件的配置 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddlew ...

  7. FFmpeg源码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  8. FFmpeg的HEVC解码器源码简单分析:概述

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  9. FFmpeg的HEVC解码器源码简单分析:解码器主干部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

随机推荐

  1. 建立qemu桥接的网络连接

    转载请注明出处谢谢:http://www.openext.org/2014/07/qemu-kvm-bridge-00     安装桥接工具:sudo apt-get install bridge-u ...

  2. poj2761(treap入门)

    给n个数,然后m个询问,询问任意区间的第k小的数,特别的,任意两个区间不存在包含关系, 也就是说,将所有的询问按L排序之后, 对于i<j ,   Li < Lj 且 Ri < Rj ...

  3. Html5 Device API详解

    三.四月曾学习过html5相关知识,并就html5 device api做过一次讲解 课程时长一个小时,预期达到level 200目标,即知道html5 device api是什么,且知道怎么实现 面 ...

  4. mysql如何更新一个表中的某个字段值等于另一个表的某个字段值

    表A和表B,现在希望更新A表,当 A.bid = B.id时,a.x = b.x, a.y=b.y,请问mysql中sql语句 update a inner join b on a.bid=b.id ...

  5. iOS游戏开发游戏功能之外的东西

    对于一个游戏的开发,我们除了完毕游戏的功能之外,还有多少东西我们须要考虑呢? 非常多.也非常烦! 但做过一遍之后下一次就会非常easy. 都有什么东西我们想加入到游戏其中呢? (1)分享功能 (2)评 ...

  6. Windows Phone开发(30):图形

    原文:Windows Phone开发(30):图形 图形如矩形.椭圆.路径等都从Shape类派生,它们一般表示规则或不规则图形,这些图形都是简单的二维图形,我相信大家都能理解的. 例一:矩形. 请看下 ...

  7. hadoop调度程序时出现“Error opening job jar”错误

    提示出现的问题: Exception in thread "main" java.io.IOException: Error opening job jar: /home/depl ...

  8. 自己写shell命令pwd

    思维:(1)得到"."的i节点号,叫n(使用stat) (2)chdir ..(使用chdir) (3)找到inode号为n的节点,得到其文件名称. 反复上述操作直到当前文件夹&q ...

  9. Mahout推荐算法ItemBased

    Mahout推荐的ItemBased 一.   算法原理 (一)    基本的 下面的例子,参见图评分矩阵:表现user,归类为item. 图(1) 该算法的原理: 1.  计算Item之间的相似度. ...

  10. centos7 设备 mariadb-10

    下载地址: http://mirrors.ustc.edu.cn/mariadb/mariadb-10.0.19/source/mariadb-10.0.19.tar.gz 由于用cmake所以线安装 ...