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. SignalR技术

    Asp.net SignalR快速入门 一.前言 之前半年时间感觉自己有点浮躁,导致停顿了半年多的时间没有更新博客,今天重新开始记录博文,希望自己可以找回初心,继续沉淀.由于最近做的项目中用到Sign ...

  2. Xamarin For Visual Studio 3.7.165 完整离线破解版

    原文 Xamarin For Visual Studio 3.7.165 完整离线破解版 Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xa ...

  3. friend keyword 对于模板 并不只不过友元!!!

    friend是C++中封装的漏网之鱼. C++中的friend同意其它的类或者是函数訪问本类的不论什么成员.甚至是private成员,仅仅要该类声明其为友元. 但是,在有些情况下,并非同意外界訪问类的 ...

  4. poj 2309 BST 使用树阵lowbit

    假设领悟了树阵lowbit,这个问题很简单,底部是奇数,使用lowbit(x)寻找x父亲,然后x父亲-1是的最大数量 至于lowbit问题是如何计算,寻找x父亲,事实上x+2^x二进制结束0的数量. ...

  5. linux 经常使用配置

    教研室用的非常旧的fedora14,装一些软件和下载东西的时候比較蛋疼,恰巧ubuntu14.04 公布,于是安装试试,顺便记录下经常使用的配置,备忘. 1. 制作镜像,比較老的主板,写入方式选择US ...

  6. Cocos2d-x 3.2 Lua演示样例 XMLHttpRequestTest(Http网络请求)

    Cocos2d-x 3.2 Lua演示样例 XMLHttpRequestTest(Http网络请求)     本篇博客介绍Cocos2d-x 3.2Lua演示样例中的XMLHttpRequestTes ...

  7. Routeros 计划任务连线/断线ADSL

    老板吩咐,要求晚上11点前断网,目的是让大家伙早睡早起. 不想使用Panabit来做策略,阿童木的D2500C还是性能不足,就用ROS的计划任务. 第1步 校时 时间要准,要不控制个乱七八糟. 操作路 ...

  8. 使用ZeroMQ(clrzmq)实现异步通信

    ZeroMQ是对Socket的封装,通过组合多种类型的结点可以实现复杂的网络通信模式.而且ZeroMQ设计简单,可以有多种平台实现,对于跨平台项目是一个福音. clrzmq是ZeroMQ的C#语言的实 ...

  9. emeditor 配置教程

    1.众多的图形界面配置功能 通过查看EmEditor的安装目录,可以发现,EmEditor有几个配置文件,理论上应该可以通过修改配置文件来达到配置EmEditor的目 的.然而,打开配置文件一看,如果 ...

  10. ProgressBar样式总结与自己主动填充方法(代码)

    有时候开发的时候须要用一个进度条告知用户眼下正在执行一个耗时操作,可是并不须要明白知道某个value来setProgress,所以就能够自己定义一个时间和进度让进度条自己主动执行了. 以下是代码: H ...