﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Jeff on Java Development-随笔分类-跟老刘学Java </title><link>http://www.blogjava.net/jeff-lau/category/28232.html</link><description>我的小宇宙要爆发了--尿急啊</description><language>zh-cn</language><lastBuildDate>Sat, 22 Dec 2007 00:28:25 GMT</lastBuildDate><pubDate>Sat, 22 Dec 2007 00:28:25 GMT</pubDate><ttl>60</ttl><item><title>中文数字</title><link>http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html</link><dc:creator>Jeff Lau</dc:creator><author>Jeff Lau</author><pubDate>Fri, 21 Dec 2007 15:09:00 GMT</pubDate><guid>http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html</guid><wfw:comment>http://www.blogjava.net/jeff-lau/comments/169466.html</wfw:comment><comments>http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jeff-lau/comments/commentRss/169466.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jeff-lau/services/trackbacks/169466.html</trackback:ping><description><![CDATA[<p>摘要：以中文的形式表示数字，在开具发票、收据的时候经常用到，尤其在金融领域。但数字的中文表示和其它语言有很大的不同，如中文以每4个数字(万)为一个小的分隔。 本文以测试驱动开发的方法，开发该功能。本程序只是用表示整数的中文形式，很容易扩展到long形式和表示人民币货币的表示形式。</p> <hr>  <p>作者：<a href="http://www.blogjava.net/jeff-lau/articles/169203.html">Jeff</a> 发表于：2006-12-02 08:12 最后更新于： <!-- #BeginDate format:Ch2m -->2007年12月21日 23:10<!-- #EndDate --> <br><a href="http://creativecommons.org/licenses/by/3.0/deed.zh">版权声明</a>：可以任意转载，转载时请务必以超链接形式标明文章<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html">原始出处</a>和作者信息及<a href="http://www.blogjava.net/jeff-lau/articles/169202.html">本版权声明</a>。<br><a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html">http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html</a> </p> <hr>  <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.test; </p> <p>import org.junit.Assert;<br>import org.junit.Test; </p> <p>import chinese.utility.ChineseNumber; </p> <p>public class ChinesNumberFormatter { </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 单个数字 0--9<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testSingleLower() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("零", new ChineseNumber(0).lower());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("五", new ChineseNumber(5).lower());<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 10--99<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void test2BitLower() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("六十八", new ChineseNumber(68).lower());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("八十", new ChineseNumber(80).lower());<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 100--999<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void test3BitLower() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("五百零八", new ChineseNumber(508).lower());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("八百", new ChineseNumber(800).lower());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 1000--9999<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void test4BitLower() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("一千零八", new ChineseNumber(1008).lower());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("一千零八十", new ChineseNumber(1080).lower()); </p> <p>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * &gt; 9999<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void test5BitLower() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("三十万零八千", new ChineseNumber(308000).lower());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("三十万零八百", new ChineseNumber(300800).lower());<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 缩写和大写一起测<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testAbbriation() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals("拾捌", new ChineseNumber(18, true).upper());<br>&nbsp;&nbsp;&nbsp; } </p> <p>} </p></div> <p>测试</p> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility; </p> <p>public class ChineseNumber { </p> <p>&nbsp;&nbsp;&nbsp; private static final int RADIX = 10; </p> <p>&nbsp;&nbsp;&nbsp; private static final String[] LOWER_UNIT = { "", "十", "百", "千", "万", "十",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "百", "千", "亿", "十", "百", "千", "万", "十", "百", "千", "万" };<br>&nbsp;&nbsp;&nbsp; private String[] LOWER = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; </p> <p>&nbsp;&nbsp;&nbsp; private static final String[] UPPER_UNIT = { "", "拾", "佰", "仟", "万", "拾",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "万" };<br>&nbsp;&nbsp;&nbsp; private String[] UPPER = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; </p> <p>&nbsp;&nbsp;&nbsp; private int number;<br>&nbsp;&nbsp;&nbsp; private boolean abbreviation; </p> <p>&nbsp;&nbsp;&nbsp; public ChineseNumber(int number, boolean isShort) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.number = number;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.abbreviation = isShort;<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; public ChineseNumber(int number) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this(number, false);<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; public String lower() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return format(LOWER, LOWER_UNIT);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; public String upper() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return format(UPPER, UPPER_UNIT);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; private String format(final String[] chinese, final String[] unit) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (number == 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return chinese[number];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (abbreviation == true &amp;&amp; canAbbreviate(number)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return formatShort(chinese, unit);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String result = ""; </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int leftNumber = number;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int rightNumber = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int currentNumber = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int bit = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (leftNumber &gt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightNumber = currentNumber;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentNumber = leftNumber % RADIX;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftNumber = leftNumber / RADIX; </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (currentNumber &gt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = chinese[currentNumber] + unit[bit] + result;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (rightNumber &gt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = chinese[currentNumber] + result;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (bit % 4 == 0 &amp;&amp; currentNumber == 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = unit[bit] + result;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bit++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result; </p> <p>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 缩写 18 为 十八 或 拾捌<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; private String formatShort(String[] chinese, String[] unit) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return unit[1] + chinese[number % RADIX];<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 能否缩写<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; private boolean canAbbreviate(int number2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (number2 &gt;= 9 &amp;&amp; number2 &lt;= 19) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp; } </p> <p>}</p></div><img src ="http://www.blogjava.net/jeff-lau/aggbug/169466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jeff-lau/" target="_blank">Jeff Lau</a> 2007-12-21 23:09 <a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169466.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中文排序</title><link>http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html</link><dc:creator>Jeff Lau</dc:creator><author>Jeff Lau</author><pubDate>Fri, 21 Dec 2007 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html</guid><wfw:comment>http://www.blogjava.net/jeff-lau/comments/169257.html</wfw:comment><comments>http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jeff-lau/comments/commentRss/169257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jeff-lau/services/trackbacks/169257.html</trackback:ping><description><![CDATA[<p>摘要：在Java中，对一个数组或列表(在本文中统称为集合)中的元素排序，是一个很经常的事情。好在Sun公司在Java库中实现了大部分功能。如果集合中的元素实现了Comparable接口，调用Array或Collections的静态(static)方法sort，就可以直接对集合排序。程序员用不同的方式实现了Comparator接口，就可以用各自不同的方式排序。对于包含汉字的字符串来说，排序的方式主要有两种：一种是拼音，一种是笔画。本文就讲述如何实现这两种不同的比较器(Comparator)。</p> <hr>  <p>作者：<a href="http://www.blogjava.net/jeff-lau/articles/169203.html">Jeff</a> 发表于：2007年12月21日 11:27 最后更新于： <!-- #BeginDate format:Ch2m -->2007年12月21日 12:38<!-- #EndDate --> <br><a href="http://creativecommons.org/licenses/by/3.0/deed.zh">版权声明</a>：可以任意转载，转载时请务必以超链接形式标明文章<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html">原始出处</a>和作者信息及<a href="http://www.blogjava.net/jeff-lau/articles/169202.html">本版权声明</a>。<br><a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html">http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html</a> </p> <hr>  <h1>排序概述</h1> <p>在Java中，对一个数组或列表(在本文中统称为集合)中的元素排序，是一个很经常的事情。好在Sun公司在Java库中实现了大部分功能。如果集合中的元素实现了Comparable接口，调用以下的静态(static)方法，就可以直接对集合排序。</p> <div class="code"> <p>// 数组排序方法<br>// 数组中的元素可以是像int这样的原生类型(primitive type), 也可以是像String这样实现了Comparable接口的类型，这里用type表示。 <br>java.util.Arrays.sort(type[] a);</p> <p>// 列表<br>public static &lt;T&gt; void sort(List&lt;T&gt; list)</p></div> <p>以上的这些排序方式能满足大部分应用。但集合中的元素没有实现Comparable接口，或者集合中的元素要按一种特别的方式排序，这要怎么办？Sun公司早就想到了，并在Java库中提供上面两个方法的重载。</p> <div class="code"> <p>// 数组排序方法。<br>// 数组中的元素可以是像int这样的原生类型(primitive type), 也可以是像String这样实现了Comparable接口的类型，这里用type表示。 <br>public static &lt;T&gt; void sort(T[] a, Comparator&lt;? super T&gt; c)</p> <p>// 列表<br>public static &lt;T&gt; void sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; c)</p></div> <p>只要实现了Comparator接口，就可以按程序员自己的意思去排序了。对于包含汉字的字符串来说，排序的方式主要有两种：一种是拼音，一种是笔画。汉字是通过一定的编码方式存储在计算机上的，主要的编码有：Unicdoe、GB2312和GBK等。</p> <h2>Unicode 编码中的汉字</h2> <p>Unicode中编码表分为两块，一个是基本的，一个是辅助的。现在的大多数操作系统还不支持Unicode中辅助区域中的文字，如WinXp。</p> <p>在Java中的字符就是Unicode码表示的。对于Unicode基本区域中的文字，用两个字节的内存存储，用一个char表示，而辅助区域中的文字用4个字节存储，因此辅助区域中的就要用两个char来表示了(表一种蓝色底就是辅助区域中的文字)。一个文字的unicode编码，在Java中统一用codePoint(代码点)这个概念。</p> <p>中文和日文、韩文一样是表意文字，在Unicode中，中日韩三国(东亚地区)的文字是统一编码的。CJK代表的就是中日韩。在这里，我把这3中文字，都作为汉字处理了。(日语和韩语可能就是从汉语中衍生的吧！)</p> <p>汉字在Unicode中的分布大致如下表：</p> <table cellspacing="0" cellpadding="2" width="400" border="1"> <tbody> <tr> <td valign="top" width="100">&nbsp;</td> <td valign="top" width="100">首字编码</td> <td valign="top" width="100">尾字编码</td> <td valign="top" width="100">个数</td></tr> <tr> <td valign="top" width="100">基本汉字</td> <td valign="top" width="100">U4E00</td> <td valign="top" width="100">U9FBF</td> <td valign="top" width="100">20928</td></tr> <tr> <td valign="top" width="100">异性字</td> <td valign="top" width="100">UF900</td> <td valign="top" width="100">UFAFF</td> <td valign="top" width="100">512</td></tr> <tr> <td valign="top" width="100">扩展A</td> <td valign="top" width="100">U3400</td> <td valign="top" width="100">U4D8F</td> <td valign="top" width="100">512</td></tr> <tr style="background-color: #ccccff" bgcolor="#ffffff"> <td valign="top" width="100">扩展B</td> <td valign="top" width="100">U20000</td> <td valign="top" width="100">U2A6DF</td> <td valign="top" width="100">42720</td></tr> <tr style="background-color: #ccccff"> <td valign="top" width="100">补充</td> <td valign="top" width="100">U2F800</td> <td valign="top" width="100">U2FA1F</td> <td valign="top" width="100">544</td></tr> <tr> <td valign="top" width="100">其他</td> <td valign="top" width="100">&nbsp;</td> <td valign="top" width="100">&nbsp;</td> <td valign="top" width="100">...</td></tr></tbody></table><a id="table1" name="table1"></a>表一<br> <p>在这些编码区间，有些编码是保留的。</p> <h2>GB2312编码</h2> <p>GB2312是中华人民共和国最早的计算机汉字编码方式。大概有6000多个汉字，这些汉字是按拼音顺序编码的。这6000多个汉字都是简体中文字。</p> <h2>GBK编码</h2> <p>GB2312的扩展，并兼容GB2312。扩展后的汉字大概有2万多个，其中有简体汉字也有繁体汉字。</p> <h1>拼音排序</h1> <p>拼音有好几种方式，其中最主要的是中华人民共和国的<a href="http://www.edu.cn/20011114/3009777.shtml">汉语拼音 Chinese Phonetic</a>。对汉字的排序有两种：一种是宽松的，能够按拼音排序最常用的汉字，另一种是严格的，能够按拼音排序绝大部分大部分汉字。</p> <h2>宽松的拼音排序法</h2> <p>原理：汉字最早是GB2312编码，收录了六千多个汉字，是按拼音排序的，编码是连续的。 后来出现了GBK编码，对GB2312进行了扩展，到了两万多汉字，并且兼容GB2312，也就是说GB2312中的汉字编码是原封不动搬到GBK中的(在GBK编码中[B0-D7]区中)。</p> <p>如果我们只关心这6000多个汉字的顺序，就可以用下面的方法实现汉字宽松排序。</p> <div class="code"> <p>/**<br>* @author Jeff <br>* <br>* Copyright (c) 复制或转载本文，请保留该注释。<br>*/</p> <p>package chinese.utility; </p> <p>import java.text.Collator; <br>import java.util.Comparator; <br>import java.util.Locale; </p> <p>public class PinyinSimpleComparator implements Comparator&lt;String&gt; { <br>&nbsp;&nbsp;&nbsp; public int compare(String o1, String o2) { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Collator.getInstance(Locale.CHINESE).compare(o1, o2); <br>&nbsp;&nbsp;&nbsp; } <br>} </p></div> <p>在对[孙, 孟, 宋, 尹, 廖, 张, 徐, 昆, 曹, 曾,怡]这几个汉字排序，结果是：[曹, 昆, 廖, 孟, 宋, 孙, 徐, 尹, 曾, 张, 怡]。最后一个<strong> 怡</strong> 有问题，不该排在最后的。 </p> <p>注意：这个程序有两个不足 </p> <ul> <li>由于gb2312中的汉字编码是连续的，因此新增加的汉字不可能再按照拼音顺序插入到已有的gb2312编码中，所以新增加的汉字不是按拼音顺序排的。  <li>同音字比较的结果不等于0 。 </li></ul> <p>下面的测试代码可以证明</p> <div class="code"> <p>/**<br>* @author Jeff <br>* <br>* Copyright (c) 复制或转载本文，请保留该注释。<br>*/</p> <p>/**<br>* 非常用字(怡)<br>*/<br>@Test<br>public void testNoneCommon() {<br>&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("怡", "张") &gt; 0); <br>}<br><br>/**<br>* 同音字<br>*/<br>@Test<br>public void testSameSound() {<br>&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("怕", "帕") != 0); <br>}<br></p></div> <h2>严格的拼音排序法</h2> <p>为了解决宽松的拼音的两点不足，可以通过实现汉语拼音的函数来解决。goolge下看到sf上有个pinyin4j的项目，可以解决这个问题，pinyin4j的项目地址是：<a href="http://pinyin4j.sourceforge.net/">http://pinyin4j.sourceforge.net/</a>。</p> <p>实现代码：</p> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility; </p> <p>import java.util.Comparator;<br>import net.sourceforge.pinyin4j.PinyinHelper; </p> <p>public class PinyinComparator implements Comparator&lt;String&gt; { </p> <p>&nbsp;&nbsp;&nbsp; public int compare(String o1, String o2) { </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; o1.length() &amp;&amp; i &lt; o2.length(); i++) { </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint1 = o1.charAt(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint2 = o2.charAt(i); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Character.isSupplementaryCodePoint(codePoint1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || Character.isSupplementaryCodePoint(codePoint2)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (codePoint1 != codePoint2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Character.isSupplementaryCodePoint(codePoint1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || Character.isSupplementaryCodePoint(codePoint2)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return codePoint1 - codePoint2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pinyin1 = pinyin((char) codePoint1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pinyin2 = pinyin((char) codePoint2); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pinyin1 != null &amp;&amp; pinyin2 != null) { // 两个字符都是汉字<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!pinyin1.equals(pinyin2)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return pinyin1.compareTo(pinyin2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return codePoint1 - codePoint2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return o1.length() - o2.length();<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 字符的拼音，多音字就得到第一个拼音。不是汉字，就return null。<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; private String pinyin(char c) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pinyins == null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return pinyins[0];<br>&nbsp;&nbsp;&nbsp; }<br>}</p></div> <p>测试：</p> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.test; </p> <p>import java.util.Comparator; </p> <p>import org.junit.Assert;<br>import org.junit.Test; </p> <p>import chinese.utility.PinyinComparator; </p> <p>public class PinyinComparatorTest { </p> <p>&nbsp;&nbsp;&nbsp; private Comparator&lt;String&gt; comparator = new PinyinComparator(); </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 常用字<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCommon() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("孟", "宋") &lt; 0);<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 不同长度<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testDifferentLength() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("他奶奶的", "他奶奶的熊") &lt; 0);<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 和非汉字比较<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testNoneChinese() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("a", "阿") &lt; 0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("1", "阿") &lt; 0);<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 非常用字(怡)<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testNoneCommon() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("怡", "张") &lt; 0);<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 同音字<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testSameSound() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("怕", "帕") == 0);<br>&nbsp;&nbsp;&nbsp; }</p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 多音字(曾)<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testMultiSound() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("曾经", "曾迪") &gt; 0);<br>&nbsp;&nbsp;&nbsp; } </p> <p>}</p></div> <p>我的这样严格的拼音排序还是有有待改进的地方，看上面测试代码的最后一个测试，就会发现：程序不会根据语境来判断多音字的拼音，仅仅是简单的取多音字的第一个拼音。</p> <h1>笔画排序</h1> <p>要按笔画排序，就要实现笔画比较器。</p> <p class="code">class StokeComparator implements Comparator&lt;String&gt; </p> <p>如果有个方法可以求得汉字的笔画数，上面的功能就很容易实现。如何求一个汉字的笔画数？最容易想到的就是查表法。建一个汉字笔画数表，如：</p> <table cellspacing="0" cellpadding="2" width="269" border="1"> <tbody> <tr> <td valign="top" width="74">汉字</td> <td valign="top" width="119">Unicode编码</td> <td valign="top" width="74">笔画数</td></tr> <tr> <td valign="top" width="74">一</td> <td valign="top" width="119">U4E00</td> <td valign="top" width="74">1</td></tr> <tr> <td valign="top" width="74">二</td> <td valign="top" width="119">U4E8C</td> <td valign="top" width="74">2</td></tr> <tr> <td valign="top" width="74">龍</td> <td valign="top" width="119">U9F8D</td> <td valign="top" width="74">16</td></tr> <tr> <td valign="top" width="74">...</td> <td valign="top" width="119">...</td> <td valign="top" width="74">...</td></tr></tbody></table>表二<br> <p>如果是连续的、按unicode编码排好顺序的表，实际存储在笔画数表中的只需最后一列就够了。</p> <p>那如何建这个表呢？这个表存储在哪里？</p> <h2>建汉字笔画数表</h2> <p>现在大多数系统还只能支持Unicode中的基本汉字那部分汉字，编码从U9FA6-U9FBF。所以我们只建这部分汉字的笔画表。汉字笔画数表，我们可以按照下面的方法生成：</p> <ol> <li>用java程序生成一个文本文件(Chinese.csv)。包括所有的从U9FA6-U9FBF的字符的编码和文字。利用excel的按笔画排序功能，对Chinese.csv文件中的内容排序。  <li>编写Java程序分析Chinese.csv文件，求得笔画数, 生成ChineseStroke.csv。矫正笔画数，重新按汉字的Unicode编码对ChineseStroke.csv文件排序。  <li>只保留ChineseStroke.csv文件的最后一列，生成Stroke.csv。 </li></ol> <p>在这里<a href="http://www.blogjava.net/Files/jeff-lau/Stroke.zip" target="_blank">下载上面3个步骤生成的3个文件</a>。</p> <h3>生成Chinese.csv的Java程序</h3> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.preface; </p> <p>import java.io.IOException;<br>import java.io.PrintWriter; </p> <p>public class ChineseCoder { </p> <p>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws IOException {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out = new PrintWriter("Chinese.csv");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 基本汉字<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(char c = 0x4E00; c &lt;= 0x9FA5; c++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println((int)c + "," + c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.flush();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.close(); </p> <p>&nbsp;&nbsp;&nbsp; } </p> <p>}</p></div> <h3>初始化笔画数</h3> <p>从Excel排序过后的Chinese.csv文件来看，排好序的文件还是有一定规律的。在文件的第9行-12行可以看出：逐行扫描的时候，当unicode会变小了，笔画数也就加1。</p> <p>20059,乛<br>20101,亅<br>19969,丁<br>19970,丂</p> <p>用下面的Java程序分析吧。</p> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.preface; </p> <p>import java.io.File;<br>import java.io.IOException;<br>import java.io.PrintWriter;<br>import java.util.Scanner; </p> <p>public class Stroke { </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * @param args<br>&nbsp;&nbsp;&nbsp;&nbsp; * @throws IOException<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws IOException {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Scanner in = new Scanner(new File("Chinese.csv"));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out = new PrintWriter("ChineseStroke.csv");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String oldLine = "999999";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stroke = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (in.hasNextLine()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = in.nextLine();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (line.compareTo(oldLine) &lt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stroke++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldLine = line;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println(line + "," + stroke);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.flush();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in.close();<br>&nbsp;&nbsp;&nbsp; } </p> <p>}</p></div> <p>上面用的这个规律有问题吗？有问题，从ChineseStroke.csv文件抽取最后几个汉字就发现，笔画数不对。为什么呢？</p> <ul> <li>笔画数可能不是连续的。  <li>n+1笔画数的最小Unicode码可能比n笔画数的最大Unicode码要大 </li></ul> <p>我们要人工核对ChineseStroke文件，但只要核对在笔画变化的那几个汉字的笔画数。最后，我发现，只有笔画数多于30的少数几个汉字的笔画数不对。核对并矫正笔画数后，用Excel按Unicode重新排序，去掉汉字和Unicode两列，只保留笔画数那列，得到Stroke.csv文件。</p> <h2>求得笔画数的方法和笔画比较器方法</h2> <h3>求得笔画数的方法测试代码： </h3> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.test; </p> <p>import static org.junit.Assert.assertEquals; </p> <p>import org.junit.Before;<br>import org.junit.Test;<br>import chinese.utility.Chinese; </p> <p>public class StrokeTest { </p> <p>&nbsp;&nbsp;&nbsp; Chinese chinese; </p> <p>&nbsp;&nbsp;&nbsp; @Before<br>&nbsp;&nbsp;&nbsp; public void setUp() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chinese = new Chinese();<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testStroke() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals(1, chinese.stroke('一'));<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testStroke2() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals(2, chinese.stroke('二'));<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testStroke16() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals(16, chinese.stroke('龍'));<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testStrokeABC() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals(-1, chinese.stroke('a'));<br>&nbsp;&nbsp;&nbsp; } </p> <p>}</p></div> <h3>求得笔画数的方法代码</h3> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility; </p> <p>import java.util.Comparator; </p> <p>public class StrokeComparator implements Comparator&lt;String&gt; { </p> <p>&nbsp;&nbsp;&nbsp; public int compare(String o1, String o2) { </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chinese chinese = new Chinese(); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; o1.length() &amp;&amp; i &lt; o2.length(); i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint1 = o1.codePointAt(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint2 = o2.codePointAt(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (codePoint1 == codePoint2)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue; </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stroke1 = chinese.stroke(codePoint1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stroke2 = chinese.stroke(codePoint2); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stroke1 &lt; 0 || stroke2 &lt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return codePoint1 - codePoint2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stroke1 != stroke2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return stroke1 - stroke2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return o1.length() - o2.length();<br>&nbsp;&nbsp;&nbsp; }<br>}</p></div> <h3>笔画比较器测试</h3> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.test; </p> <p>import java.util.Comparator; </p> <p>import org.junit.Assert;<br>import org.junit.Before;<br>import org.junit.Test; </p> <p>import chinese.utility.StrokeComparator; </p> <p>public class StrokeComparatorTest { </p> <p>&nbsp;&nbsp;&nbsp; private Comparator&lt;String&gt; comparator;<br>&nbsp;&nbsp;&nbsp; @Before<br>&nbsp;&nbsp;&nbsp; public void setUp() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comparator = new StrokeComparator();<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 相同笔画数<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCompareEquals() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("一", "丨") == 0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 不同笔画数<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCompare() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("一", "二") &lt; 0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("唔", "马") &gt; 0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 长度不同<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCompareDefficultLength() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("二", "二一") &lt; 0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 非汉字的比较<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testABC() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("一", "a") &gt; 0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("a", "b") &lt; 0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>}</p></div> <h3>笔画比较器 </h3> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility.test; </p> <p>import java.util.Comparator; </p> <p>import org.junit.Assert;<br>import org.junit.Before;<br>import org.junit.Test; </p> <p>import chinese.utility.StrokeComparator; </p> <p>public class StrokeComparatorTest { </p> <p>&nbsp;&nbsp;&nbsp; private Comparator&lt;String&gt; comparator;<br>&nbsp;&nbsp;&nbsp; @Before<br>&nbsp;&nbsp;&nbsp; public void setUp() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comparator = new StrokeComparator();<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 相同笔画数<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCompareEquals() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("一", "丨") == 0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 不同笔画数<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCompare() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("一", "二") &lt; 0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("唔", "马") &gt; 0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 长度不同<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testCompareDefficultLength() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("二", "二一") &lt; 0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 非汉字的比较<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; @Test<br>&nbsp;&nbsp;&nbsp; public void testABC() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("一", "a") &gt; 0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(comparator.compare("a", "b") &lt; 0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>}</p></div> <h1>其他程序的汉字排序</h1> <p>Microsoft在这方面做得比较好。如Sql server 2000，Word和Excel都能按拼音和笔画排序。而Oracle只能是采取宽松拼音排序法。 </p><img src ="http://www.blogjava.net/jeff-lau/aggbug/169257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jeff-lau/" target="_blank">Jeff Lau</a> 2007-12-21 11:29 <a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中文排序 － 笔画</title><link>http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html</link><dc:creator>Jeff Lau</dc:creator><author>Jeff Lau</author><pubDate>Thu, 20 Dec 2007 12:39:00 GMT</pubDate><guid>http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html</guid><wfw:comment>http://www.blogjava.net/jeff-lau/comments/169147.html</wfw:comment><comments>http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jeff-lau/comments/commentRss/169147.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jeff-lau/services/trackbacks/169147.html</trackback:ping><description><![CDATA[<p>摘要：在很多中文书籍的作者页中，有很多作者的话，很多时候，是按作者姓名的笔画顺序排序的。Microsoft的Excel和Sql Server实现了按笔画排序的功能。那按笔画顺序排序，在Java中究竟怎样实现呢？</p> <hr>  <p>作者：<a href="http://www.blogjava.net/jeff-lau/articles/169203.html">Jeff</a> 发表于：2007-12-20 20:39 最后更新于： <!-- #BeginDate format:Ch2m -->2007年12月21日 12:17<!-- #EndDate --> <br><a href="http://creativecommons.org/licenses/by/3.0/deed.zh">版权声明</a>：可以任意转载，转载时请务必以超链接形式标明文章<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html">原始出处</a>和作者信息及<a href="http://www.blogjava.net/jeff-lau/articles/169202.html">本版权声明</a>。<br><a href="http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html">http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html</a> </p> <hr>  <h1>合并了</h1> <p>已经将《<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html">中文排序--笔画</a>》和《<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html">中文排序--汉语拼音</a>》修改并合并《<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html">中文排序</a>》中。这里只保留最后的代码。实现的原理和方法请见<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html">中文排序</a></p> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility; </p> <p>import java.util.Comparator; </p> <p>public class StrokeComparator implements Comparator&lt;String&gt; { </p> <p>&nbsp;&nbsp;&nbsp; public int compare(String o1, String o2) { </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chinese chinese = new Chinese(); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; o1.length() &amp;&amp; i &lt; o2.length(); i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint1 = o1.codePointAt(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint2 = o2.codePointAt(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (codePoint1 == codePoint2)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue; </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stroke1 = chinese.stroke(codePoint1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stroke2 = chinese.stroke(codePoint2); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stroke1 &lt; 0 || stroke2 &lt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return codePoint1 - codePoint2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stroke1 != stroke2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return stroke1 - stroke2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return o1.length() - o2.length();<br>&nbsp;&nbsp;&nbsp; }<br>}</p></div><img src ="http://www.blogjava.net/jeff-lau/aggbug/169147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jeff-lau/" target="_blank">Jeff Lau</a> 2007-12-20 20:39 <a href="http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中文排序 － 汉语拼音</title><link>http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html</link><dc:creator>Jeff Lau</dc:creator><author>Jeff Lau</author><pubDate>Wed, 19 Dec 2007 00:30:00 GMT</pubDate><guid>http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html</guid><wfw:comment>http://www.blogjava.net/jeff-lau/comments/168637.html</wfw:comment><comments>http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jeff-lau/comments/commentRss/168637.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jeff-lau/services/trackbacks/168637.html</trackback:ping><description><![CDATA[<p>摘要：中文一般都是按拼音来排序的。但Java中的String类是按Unicode编码存储数据的，因此，String类也是按Unicode编码的大小来排序的。Sun公司提供一个Collator类来重新按不同的规则对字符串排序，但Collator对中文的排序方式只是不严格的拼音排序法。Microsoft的Excel和Sql Server实现了按拼音排序的功能，就比Collator实现的好多了。那如何在Java中实现类似Microsoft的拼音排序的方式呢？</p> <hr>  <p>作者：<a href="http://www.blogjava.net/jeff-lau/articles/169203.html">Jeff</a> 发表于：2007-12-19 08:30 最后更新于： <!-- #BeginDate format:Ch2m -->2007年12月21日 12:33<!-- #EndDate --> <br><a href="http://creativecommons.org/licenses/by/3.0/deed.zh">版权声明</a>：可以任意转载，转载时请务必以超链接形式标明文章<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html">原始出处</a>和作者信息及<a href="http://www.blogjava.net/jeff-lau/articles/169202.html">本版权声明</a>。<br><a href="http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html">http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html</a> </p> <hr>  <h1>合并了</h1> <p>已经将《<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/20/169147.html">中文排序--笔画</a>》和《<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html">中文排序--汉语拼音</a>》修改并合并《<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html">中文排序</a>》中。这里只保留最后的代码。实现的原理和方法请见<a href="http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html">中文排序</a>。</p> <div class="code"> <p>/**<br>&nbsp; * @author Jeff <br>&nbsp; * <br>&nbsp; * Copyright (c) 复制或转载本文，请保留该注释。<br>&nbsp; */<br>package chinese.utility; </p> <p>import java.util.Comparator;<br>import net.sourceforge.pinyin4j.PinyinHelper; </p> <p>public class PinyinComparator implements Comparator&lt;String&gt; { </p> <p>&nbsp;&nbsp;&nbsp; public int compare(String o1, String o2) { </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; o1.length() &amp;&amp; i &lt; o2.length(); i++) { </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint1 = o1.charAt(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int codePoint2 = o2.charAt(i); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Character.isSupplementaryCodePoint(codePoint1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || Character.isSupplementaryCodePoint(codePoint2)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (codePoint1 != codePoint2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Character.isSupplementaryCodePoint(codePoint1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || Character.isSupplementaryCodePoint(codePoint2)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return codePoint1 - codePoint2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pinyin1 = pinyin((char) codePoint1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pinyin2 = pinyin((char) codePoint2); </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pinyin1 != null &amp;&amp; pinyin2 != null) { // 两个字符都是汉字<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!pinyin1.equals(pinyin2)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return pinyin1.compareTo(pinyin2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return codePoint1 - codePoint2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return o1.length() - o2.length();<br>&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp;&nbsp; * 字符的拼音，多音字就得到第一个拼音。不是汉字，就return null。<br>&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; private String pinyin(char c) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pinyins == null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return pinyins[0];<br>&nbsp;&nbsp;&nbsp; }<br>}</p></div><img src ="http://www.blogjava.net/jeff-lau/aggbug/168637.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jeff-lau/" target="_blank">Jeff Lau</a> 2007-12-19 08:30 <a href="http://www.blogjava.net/jeff-lau/archive/2007/12/19/168637.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟老刘学Java (一)</title><link>http://www.blogjava.net/jeff-lau/archive/2007/12/19/168636.html</link><dc:creator>Jeff Lau</dc:creator><author>Jeff Lau</author><pubDate>Tue, 18 Dec 2007 20:48:00 GMT</pubDate><guid>http://www.blogjava.net/jeff-lau/archive/2007/12/19/168636.html</guid><wfw:comment>http://www.blogjava.net/jeff-lau/comments/168636.html</wfw:comment><comments>http://www.blogjava.net/jeff-lau/archive/2007/12/19/168636.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/jeff-lau/comments/commentRss/168636.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jeff-lau/services/trackbacks/168636.html</trackback:ping><description><![CDATA[<p>老刘是个Java高手了，小刘是个Java菜鸟，最近小刘跟着老刘开始学Java。你问我，小刘和老刘什么关系？也许他们是兄妹吧。小刘是个MM啊，她漂亮吗，QQ号是多少，MSN呢……闲话少说，言归正传。</p> <p>(小刘走向正在玩电脑的老刘身边)</p> <p>小刘：老刘！(小刘一直都是这么称呼老刘的)。教我学Java吧！</p> <p>老刘：好！(对于小刘的要求，老刘从没拒绝过)</p> <p>小刘：可我对Java什么都不会！</p> <p>老刘：有我在，一切都没问题！(在小刘面前，老刘总喜欢吹嘘。)我们先装个Java开发运行环境吧。</p> <p>小刘：好呢！</p> <p>老刘：我们先到Sun公司的网站下载一个JDK。JDK就是用来开发Java的工具。</p> <p>小刘：Sun？就是天上的那个太阳啊！原来Java是太阳公司的啊！</p> <p>老刘：基本上可以这么说。其他公司也有JDK产品。比如：IBM。</p> <p>小刘：IBM我知道。被我国的联想公司收购了嘛！</p> <p>老刘：(轻轻笑了一下)，就是那个IBM。不过联想只收购了IBM的一个部门而已。</p> <p>&nbsp;</p> <p>(小刘在老刘的指导下，从SUN网站下载一个最新的JDK，现在正在下载中……)</p> <p>小刘：刚才在SUN网站，我看到有个Java SE, Java EE,还有个……</p> <p>老刘：还有Java ME。这是Java为不同的运行环境准备的3种不同版本，他们用的都是Java语言，学好Java语言就能开发3种不同应用程序了(Java在这3种版本除了使用的Java的语法相同外，还有很多很多不同的东西要掌握，才能不同完成开发工作，为了不打击小刘学习的积极性，把SUN蒙人的那套也用上了)。Java SE是Java的标准版，Java ME是用于手机软件开发的，Java EE是用于企业应用开发，比如网站啊。</p> <p>小刘：Java还能建网站。我学会Java，就能用Java建一个自己漂亮的个人网站了。(托着下巴，仰着头开始遐想了……)</p> <p>老刘：(晕*******，路途遥远着了)那就先学好Java吧。</p> <p>(小刘回到现实，老刘继续解释)</p> <p>老刘：Java SE可以说其他版本的基础。我们就学Java SE。现在最新的Java SE是6.0，下载页面在<a title="Java SE下载地址" href="http://java.sun.com/javase/downloads/index.jsp" target="_blank">http://java.sun.com/javase/downloads/index.jsp</a>。</p> <p>&nbsp;</p> <p>(电脑提示：下载成功了)</p> <p>老刘：现在安装吧。<strong>注意：Java的默认目录是C:\Program Files\..., 最好不要把Java带有空格的路径中。</strong>我们安装在D:\java目录中吧。Java SE安装包中，除了JDK，还有JRE。装好JDK后，会提示你是否安装JRE，我们一起安装了吧。</p> <p>小刘：什么是JRE？</p> <p>老刘：JRE就是Java运行环境。如果你只想运行Java程序，就不用安装JDK，只需要安装一个JRE就够了。现在安装好了。我们来写第一个全世界最有名的程序：HelloWorld。</p> <p>(老刘用记事本创建下面一个文件：HelloWorld.java)</p> <p><code>public class HelloWorld {<br><br>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello World!");<br>&nbsp;&nbsp;&nbsp; } <br><br>}</code> </p> <p>&nbsp;</p> <p>(老刘打开命令窗口，输入：javac HelloWorld.java。电脑显示：'javac' 不是内部或外部命令，也不是可运行的程序或批处理文件。)</p> <p>老刘：我们的电脑是WinXP系统，和Win2000一样，都是WinNT系统的。设置一下环境变量，就能正常编译了。</p> <p>老刘通过点击 我的电脑 --&gt; 属性 --&gt; 高级 --&gt; 环境变量 打开了环境变量设置对话框。在系统变量中加入</p> <p>JAVA_HOME=D:\java&nbsp;&nbsp; (新建的)</p> <p>path=%JAVA_HOME%\bin; (追加在path变量最前面)</p> <p>&nbsp;</p> <p>(老刘再次打开命令窗口，输入：javac HelloWorld.java。正常了。输入：java HelloWorld。电脑显示Hello World!)</p> <p>老刘：先休息一下。等会儿你自己照我刚才那样，写一个HelloWorld.java文件，并编译和运行它。</p> <p>小刘：好的。</p> <p>(小刘是个好学的菜鸟，不休息就开始她的第一个Java程序了……)</p> <p>&nbsp;</p> <p>(HelloWorld.java虽然简单短小，粗心的小刘也输错了。在编译的时候出来了一堆错误，在老刘的帮助下，一一改正了这些错误。运行成功的时候，小刘高兴的跳了起来。觉得自己已经是Java高手了。高兴过后，小刘满心疑问……)</p> <p>小刘：老刘！这些代码中的单词都什么意思？ </p> <p>老刘：这么，明天再讲吧！</p><img src ="http://www.blogjava.net/jeff-lau/aggbug/168636.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jeff-lau/" target="_blank">Jeff Lau</a> 2007-12-19 04:48 <a href="http://www.blogjava.net/jeff-lau/archive/2007/12/19/168636.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>