瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          在java中使用TreeMap進(jìn)行中文排序(轉(zhuǎn))

          Posted on 2011-05-20 11:36 瘋狂 閱讀(2196) 評論(0)  編輯  收藏 所屬分類: java
           最近工作遇到需要按一個model中不同的列進(jìn)行排序的問題,查了一下JDK API文檔,發(fā)現(xiàn),java中可以排序的工具類和接口共有五個SortedMap 、SortedSet、TreeMap 、TreeSet和Collections,由于我要排序的是一系列model,所以,最后使用了TreeMap對象,而且TreeMap到最后的處理比較自由,可以直接返回TreeMap對象,也可以返回model的一個Collection對象。其它幾個類的用法其實(shí)都是大同小異,如果java基礎(chǔ)較好,看一下API文檔很容易明白,只是Collection中需要顯式調(diào)用sort()方法而已。

             寫理論的東西或者深入的東西就會太多了,而且讓人會看得比較煩,這里講求實(shí)用,就不多說了,直接入正體,基本的排序代碼如下:
            package ChineseSort;

          import java.util.Collection;

          import java.util.Iterator;

          import java.util.SortedMap;

          import java.util.TreeMap;

          public class TestSort {

          public static void main(String[] args) {

              // TODO Auto-generated method stub    

              TreeMap map = new TreeMap();      

              for(int i=0; i<10; i++) {

                  String  s = ""+(int)(Math.random()*1000);

                  map.put(s,s);

              }

              map.put("abcd","abcd");

              map.put("Abc", "Abc");

              map.put("bbb","bbb");

              map.put("BBBB", "BBBB");

              map.put("北京","北京");

              map.put("中國","中國");

              map.put("上海", "上海");

              map.put("廈門", "廈門");

              map.put("香港", "香港");

              map.put("碑海", "碑海");

              Collection col = map.values();

              Iterator it = col.iterator();

              while(it.hasNext()) {

                  System.out.println(it.next());

              }

          }

          }

             代碼就不多作解釋了,一看就明白,開始放進(jìn)去10個整數(shù)隨機(jī)數(shù),然后是英文,然后是中文。運(yùn)行結(jié)果如下:

          132

          205

          287

          295

          399

          410

          411

          464

          670

          73

          Abc

          BBBB

          abcd

          bbb

          上海

          中國

          北京

          廈門

          碑海

          香港

              注意,這里的數(shù)字排序正常,而英文排序是區(qū)分大小寫的,這個也是正常的,因?yàn)锳SCII碼中小寫字母比大寫字母靠后,中文排序則明顯的不正確,碑和北明顯應(yīng)該在一起的,而且應(yīng)該在最前面。這個主要是java中使用中文編碼GB2312或者JBK時,char型轉(zhuǎn)換成int型得過程出現(xiàn)了比較大的偏差,很多文章介紹過了,大家可以去網(wǎng)上找一下,這里不多說了,直接尋找解決方案。

             Java中之所以出現(xiàn)偏差,主要是compare方法的問題,所以這里自己實(shí)現(xiàn)Comparator接口,而國際化的問題,使用Collator類來解決。這里先解決中文問題,代碼如下:

          package ChineseSort;

          import java.text.CollationKey;

          import java.text.Collator;

          import java.util.Comparator;

          public class CollatorComparator implements Comparator {

          Collator collator = Collator.getInstance();

          public int compare(Object element1, Object element2) {

              CollationKey key1 = collator.getCollationKey(element1.toString());

              CollationKey key2 = collator.getCollationKey(element2.toString());

              return key1.compareTo(key2);

          }

          }

              同時修改我們前面完成的TestSort類,找到TreeMap map = new TreeMap();

              修改為

              CollatorComparator comparator = new CollatorComparator();

              TreeMap map = new TreeMap();

              再次運(yùn)行該類,運(yùn)行結(jié)果如下:

          325

          62

          653

          72

          730

          757

          874

          895

          909

          921

          Abc

          abcd

          bbb

          BBBB

          碑海

          北京

          上海

          廈門

          香港

          中國

             此時可以看到中文的排序已經(jīng)完成正常。如果想不讓英文區(qū)分大小寫,則修改CollatorComparator類,找到

              element1.toString()

              修改為:

              element1.toString().toLowerCase()

              當(dāng)然你改成轉(zhuǎn)換成大寫的也無所謂了,當(dāng)然element2.toString()也要同時修改為element2.toString().toLowerCase()。再次運(yùn)行結(jié)果如下:

          207

          353

          656

          659

          770

          789

          857

          861

          931

          984

          Abc

          abcd

          bbb

          BBBB

          碑海

          北京

          上海

          廈門

          香港

          中國

              現(xiàn)在可以看到,排序已經(jīng)完全符合我們的要求了。如果要反向排序也很容易,遍歷的時候倒過來,或者你寫兩個Comparator的實(shí)現(xiàn)類,正向的排序就像我們前面所寫的,反向排序就將return key1.compareTo(key2);修改成return -key1.compareTo(key2);,加了個負(fù)號,這里你可以直接加個符號看看效果,結(jié)果我就不寫了,肯定中國是Number One。我還真沒找到TreeMap里直接反向的方法,誰看到了告訴我。

              最后一些要說明的,這里我就不再寫實(shí)現(xiàn)的代碼了,就是我們要實(shí)現(xiàn)的是根據(jù)model中的一個列進(jìn)行排序,而我們測試代碼只是簡單的一些值,這個容易,遍歷所有model,把要排序的列值取出來作為TreeMap的key,然后model放進(jìn)去作為value就行了,這個很簡單,如果想寫成稍微通用點(diǎn)的,就使用反射機(jī)制,把取值方法封裝一下就行了,然后把model對象和方法名扔進(jìn)去就行了。至于value值重復(fù)的問題,也好辦,只要value相同只要不是多列同時作為排序的鍵,那么他們之間的前后順序無所謂,判斷一下當(dāng)前Map中是否含有該key值,存在,則新的key做成value+longtime就行了,就是加個時間戳(感覺用時間戳比較方便,其它的能區(qū)分的辦法也行啦)。至于多列的排序,其實(shí)也容易,按照列的前后順序firstvalue+secondvalue+......組成key放到TreeMap里照樣OK J 方便吧。

          主站蜘蛛池模板: 贡山| 宁明县| 石楼县| 贵州省| 安福县| 墨竹工卡县| 沂源县| 海城市| 巩义市| 漯河市| 宁波市| 康乐县| 富民县| 云阳县| 上栗县| 湖北省| 酒泉市| 阳朔县| 伊宁县| 吴江市| 册亨县| 永年县| 黎川县| 岐山县| 融水| 黎城县| 宁远县| 阿坝县| 军事| 南阳市| 渑池县| 新化县| 韶关市| 兴仁县| 堆龙德庆县| 仁布县| 海淀区| 且末县| 宣汉县| 博罗县| 沙坪坝区|