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

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

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

新建一个ConvertTest.java

package demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import net.sourceforge.pinyin4j.PinyinHelper; public class ConvertTest { public static void main(String[] args) {
String src = "我们中间出了一个叛徒";
char[] arr = src.toCharArray();
System.out.println("数组长度是:"+arr.length);
System.out.print("原始顺序:");
for (char temp : arr) {
System.out.print(temp+" ");
}
System.out.println();
convertToHanyuPinyin(arr);
} private static List<String> convertToHanyuPinyin(char[] array){
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < array.length; i++) {
//得到拼音首字母
String value = (PinyinHelper.toHanyuPinyinStringArray(array[i]))[0].substring(0, 1);
map.put(String.valueOf(array[i]), value);
}
System.out.println(map);
List<String> list = sort(map);
return list;
} private static List<String> sort(Map map){
List<Map.Entry<String, String>> infoIds =
new ArrayList<Map.Entry<String, String>>(map.entrySet());
// 对HashMap中的 value 进行排序
Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1,
Map.Entry<String, String> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
}); List<String> list = new ArrayList<String>();
/*****************FOR TEST***********************/
List<String> letterList = new ArrayList<String>();
/*****************FOR TEST***********************/
// 对HashMap中的 value 进行排序后 显示排序结果
for (int i = 0; i < infoIds.size(); i++) {
Map.Entry<String,String> entry = infoIds.get(i);
list.add(entry.getKey());
letterList.add(entry.getValue());
} /*****************FOR TEST***********************/
System.out.print("自然顺序:");
for (String string : list) {
System.out.print(string + " ");
} System.out.println(); System.out.print("字母顺序:");
for (String string : letterList) {
System.out.print(string +" ");
}
/*****************FOR TEST***********************/
return list;
}
}

输出结果为:

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

简单说一下步骤:

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 + 鼠标左键。

static public String[] toHanyuPinyinStringArray(char ch)
{
return getUnformattedHanyuPinyinStringArray(ch);
}

继续跟踪代码

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

调用ChineseToPinyinResource示例的getHanyuPinyinStringArray方法

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

关键的方法getHanyuPinyinRecordFromChar

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

就是如下图的资源:

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. LeetCode: Valid Palindrome [125]

    [题目] Given a string, determine if it is a palindrome, considering only alphanumeric characters and i ...

  2. Javascript语言精粹之Array常用方法分析

    Javascript语言精粹之Array常用方法分析 1.Array常用方法分析 1.1 Array.prototype.sort() Javascript的默认比较函数假定被排序元素都是字符串,所以 ...

  3. PyUnit框架学习

    http://www.oschina.net/question/12_27127#INSTALL http://www.360doc.com/content/11/0606/23/54470_1221 ...

  4. Android kxml解析WBXML

     WAP Binary XML定义好XML片断表述出同步server地址.远程数据库名称.登录账号等等内容一.两种訪问方法: 眼下的kxml支持两种wap格式:WBXML/WML. 而有两种方法将解析 ...

  5. OpenCms创建网站的过程示意图——专用OpenCms人们刚开始学习

    很多人听说过OpenCms,我知道它的强大,只需下载并安装,最后,我们看到了久违OpenCms,我们看到了它的简单的界面,喜悦之后,但难免困惑.如何用这个东西,我如何用它来网站,从哪里开始,无从下手. ...

  6. Android build-tools升级到23.0.0_rc1无法解决编译后的问题

    背景 作为项目要改变android studio,它采取了.他们主动向我,结果下载了最新的build-tools 23.0.0_rc1,然后,当我再次使用eclipse不了了.git reset了n次 ...

  7. C语言 cgi(3)

    1cs3157 – Advanced ProgrammingSummer 2014, Project 1, 150 pointsJune 17, 2014Follow these step-by-st ...

  8. 获取LayoutInflater的三种方式

    1.LayoutInflater.from(mContext); 2.Activity类的getLayoutInflater 3.(LayoutInflater)mContext.getSystemS ...

  9. JavaBean编程的基本思路-逻辑业务层

    JavaBean是Java类别.为了实现业务逻辑层. 你是什么意思?我有一个很长的故事短:我们知道,JSP编程是Java编写的代码html文件.和JavaBean编程是Java写在另一个代码JAVA类 ...

  10. Android程序猿学习路径

    而一些工作,而不仅仅是通信毕业生,很多学生没有工作或熟练Android工作人员指导的情况下,,如何学习Android而提高Android更多关注的水平. 享: 1.Android知识 1.1.站点资源 ...