從制造到創造
          軟件工程師成長之路
          posts - 292,  comments - 96,  trackbacks - 0

          在項目開發中,經常會遇到一些排序的問題。
          現在有一個操作VO(Member),它有三個屬性,分別為:id(String)、name(String)和age(int)。

          情景一:


              初始頁面,Member對象會以id排序,現在name中保存的是英文名,需對name進行排序;

          首先我們來看我們要用到的Java API中的一個接口Comparator

          public interface Comparator<T>

          比較函數強行對某些對象 collection 進行整體排序。可以將 Comparator 傳遞給 sort 方法(如 Collections.sort),從而允許在排序順序上實現精確控制。還可以使用 Comparator 來控制某些數據結構(如 TreeSet 或 TreeMap)的順序。

          當且僅當對于一組元素 S 中的每個 e1 和 e2 而言,(compare((Object)e1, (Object)e2)==0) 與 e1.equals((Object)e2) 具有相等的布爾值時,Comparator c 強行對 S 進行的排序才叫做與等號一致 的排序。

           

          也就是說,只要我們新建一個類用于排序,實現Comparator接口的compare()就可以了;

              public int compare(Object op1, Object op2) {
                  Member memberOp1 
          = (Member) op1;
                  Member memberOp2 
          = (Member) op2;

                  
          // 按姓名(英文)排序
                  return memberOp1.getName().compareTo(memberOp2.getName());
              }


          然后在使用時通過調用Collections.sort()就可以了;

          具體步驟如下:
          1、新建一個工程Object排序,然后建三個包,一個為:com.coderdream.util,用于存放“比較工具類”;另一個為:com.coderdream.view,用于存放操作VO,另一個包名為:com.coderdream.service,存放操作VO的類,這里我寫兩個測試類,分別用于測試中英文。


          代碼1:

          /*
           * Member.java 
           * 
           * Provider: CoderDream's Studio
           * 
           * History
           *   Date(DD/MM/YYYY)    Author          Description
           * ----------------------------------------------------------------------------
           *    2007/12/19        CoderDream          Created
           
          */
          package com.coderdream.view;

          /**
           * discription: 操作對象VO
           * 
           * 
          @author CoderDream
           * 
           
          */
          public class Member {

              
          /**
               * ID
               
          */
              
          private String id;

              
          /**
               * 名字
               
          */
              
          private String name;

              
          /**
               * 年齡
               
          */
              
          private int age;

              
          /**
               * 
          @param name
               * 
          @param age
               
          */
              
          public Member(String id, String name, int age) {
                  
          this.id = id;
                  
          this.name = name;
                  
          this.age = age;
              }

              
          /**
               * 
          @return
               
          */
              
          public String getName() {
                  
          return name;
              }

              
          /**
               * 
          @param name
               
          */
              
          public void setName(String name) {
                  
          this.name = name;
              }

              
          /**
               * 
          @return
               
          */
              
          public int getAge() {
                  
          return age;
              }

              
          /**
               * 
          @param age
               
          */
              
          public void setAge(int age) {
                  
          this.age = age;
              }

              
          /**
               * 
          @return the id
               
          */
              
          public String getId() {
                  
          return id;
              }

              
          /**
               * 
          @param id
               *            the id to set
               
          */
              
          public void setId(String id) {
                  
          this.id = id;
              }

          }

          代碼2:

          /*
           * CompareName.java 
           * 
           * Provider: CoderDream's Studio
           * 
           * History
           *   Date(DD/MM/YYYY)    Author          Description
           * ----------------------------------------------------------------------------
           *    2007/12/19        CoderDream          Created
           
          */
          package com.coderdream.util;

          import java.util.Comparator;

          import com.coderdream.view.Member;

          /**
           * discription:根據英文字母比較 
           *
           * 
          @author CoderDream
           *
           
          */
          public class CompareName implements Comparator {
              
              
          public int compare(Object op1, Object op2) {
                  Member memberOp1 
          = (Member) op1;
                  Member memberOp2 
          = (Member) op2;

                  
          // 按姓名(英文)排序
                  return memberOp1.getName().compareTo(memberOp2.getName());
              }
          }

          代碼3:

          /*
           * CompareAge.java 
           * 
           * Provider: CoderDream's Studio
           * 
           * History
           *   Date(DD/MM/YYYY)    Author          Description
           * ----------------------------------------------------------------------------
           *    2007/12/19        CoderDream          Created
           
          */
          package com.coderdream.util;

          import java.util.Comparator;
          import com.coderdream.view.Member;

          /**
           * discription: 根據年齡比較,由小到大
           * 
           * 
          @author CoderDream
           *
           
          */
          public class CompareAge implements Comparator {
              
              
          public int compare(Object op1, Object op2) {
                  Member memberOp1 
          = (Member) op1;
                  Member memberOp2 
          = (Member) op2;

                  
          // 按年齡排序
                  return memberOp1.getAge() < memberOp2.getAge() ? 0 : 1;
              }
          }

          代碼4:

          /*
           * Client1.java 
           * 
           * Provider: CoderDream's Studio
           * 
           * History
           *   Date(DD/MM/YYYY)    Author          Description
           * ----------------------------------------------------------------------------
           *    2007/12/19        CoderDream          Created
           
          */
          package com.coderdream.service;

          import java.util.ArrayList;
          import java.util.Collections;
          import java.util.List;
          import com.coderdream.util.CompareAge;
          import com.coderdream.util.CompareName;
          import com.coderdream.view.Member;

          /**
           * discription:測試類1,按字母和年齡比較 
           *
           * 
          @author CoderDream
           *
           
          */
          public class Client1 {

              
          /**
               * 
          @param args
               
          */
              
          public static void main(String[] args) {
                  
          // 新建鏈表并加入元素
                  List<Member> members = new ArrayList<Member>();
                  members.add(
          new Member("01""Andy"20));
                  members.add(
          new Member("02""Dell"26));
                  members.add(
          new Member("03""Felex"24));
                  members.add(
          new Member("04""Bill"21));
                  members.add(
          new Member("05""Cindy"28));

                  
          // 輸出排序后的鏈表
                  System.out.println("Original Data: ");
                  
          for (Member member : members) {
                      System.out.println(
          "  "+ member.getName() + ":" + member.getAge());
                  }

                  
          // 按名字排序
                  Collections.sort(members, new CompareName());
                  System.out.println(
          "Sort by Name: ");
                  
          // 輸出排序后的鏈表
                  for (Member member : members) {
                      System.out.println(
          "  " + member.getName() + ":" + member.getAge());
                  }

                  
          // 按年齡排序
                  Collections.sort(members, new CompareAge());
                  System.out.println(
          "Sort by Age:");
                  
          // 輸出排序后的鏈表
                  for (Member member : members) {
                      System.out.println(
          "  " + member.getName() + ":" + member.getAge());
                  }
              }

          }

          運行結果:

          Original Data: 
            Andy:
          20
            Dell:
          26
            Felex:
          24
            Bill:
          21
            Cindy:
          28
          Sort by Name: 
            Andy:
          20
            Bill:
          21
            Cindy:
          28
            Dell:
          26
            Felex:
          24
          Sort by Age:
            Andy:
          20
            Bill:
          21
            Felex:
          24
            Dell:
          26
            Cindy:
          28


          情景二:


              初始頁面,Member對象會以id排序,現在name中保存的是中文名(字符集為GBK,包括簡體中文和繁體中文),需對name進行排序;

               這里我們要用到SourceForge的pinyin4j項目的jar包,可以解決這個問題,pinyin4j的項目地址是: http://pinyin4j.sourceforge.net/ ,本文最后的源代碼中已包含此Jar包。
               
               注意,由于這里要比較的是對象,所以我們實現接口:Comparator<Object> 
               這里我們會用到包中PinyinHelper類的toHanyuPinyinStringArray(char c)方法,該方法返回該字的漢語拼音數組:

                  //返回該字的漢語拼音數組,如“王”字返回:[wang2, wang4],說明該字有兩種讀法,分別為wang2,第二聲,wang4,第四聲
                  String[] a = PinyinHelper.toHanyuPinyinStringArray(c);

          代碼5:

          /*
           * CompareNamePinyin.java 
           * 
           * Provider: CoderDream's Studio
           * 
           * History
           *   Date(DD/MM/YYYY)    Author          Description
           * ----------------------------------------------------------------------------
           *    2007/12/19        CoderDream          Created
           
          */
          package com.coderdream.util;

          import java.util.Comparator;
          import net.sourceforge.pinyin4j.PinyinHelper;
          import com.coderdream.view.Member;


          /**
           * discription:根據漢語拼音比較,第一個字相同再比較第二個字 
           *
           * 
          @author CoderDream
           *
           
          */
          public class CompareNamePinyin implements Comparator<Object> {
              
              
          public int compare(Object obj1, Object obj2) {
                  Member m1 
          = (Member)obj1;
                  Member m2 
          = (Member)obj2;
                  String o1 
          = m1.getName();
                  String o2 
          = m2.getName();
                  
                  
          for (int i = 0; i < o1.length() && i < o2.length(); i++) {
                      
          char c1 = o1.charAt(i);
                      
          char c2 = o2.charAt(i);

                      String pinyin1 
          = pinyin(c1);
                      String pinyin2 
          = pinyin(c2);

                      
          if (pinyin1 != null && pinyin2 != null) {

                          
          if (!pinyin1.equals(pinyin2)) {
                              
          return pinyin1.compareTo(pinyin2);
                          }
                      } 
          else {
                          
          if (c1 != c2) {
                              
          return c1 - c2;
                          }
                      }
                  }
                  
                  
          return o1.length() - o2.length();
              }

              
          /**
               * 字符的拼音,多音字就得到第一個拼音。不是漢字,就return null。
               * 
               * 
          @param c
               * 
          @return
               
          */
              
          private String pinyin(char c) {
                  
          //返回該字的漢語拼音數字,如“王”字返回:[wang2, wang4]
                  // 說明該字有兩種讀法,分別為wang2,第二聲,wang4,第四聲
                  String[] a = PinyinHelper.toHanyuPinyinStringArray(c);
                  
          if (a == null){
                      
          return null;
                  }
                  
          return a[0];
              }

          }
          代碼6:
          /*
           * Client2.java 
           * 
           * Provider: CoderDream's Studio
           * 
           * History
           *   Date(DD/MM/YYYY)    Author          Description
           * ----------------------------------------------------------------------------
           *    2007/12/19        CoderDream          Created
           
          */
          package com.coderdream.service;

          import java.util.ArrayList;
          import java.util.Collections;
          import java.util.List;
          import com.coderdream.util.CompareAge;
          import com.coderdream.util.CompareNamePinyin;
          import com.coderdream.view.Member;

          /**
           * discription: 測試類2,按字母和年齡比較 
           *
           * 
          @author CoderDream
           *
           
          */
          public class Client2 {

              
          /**
               * 
          @param args
               
          */
              
          public static void main(String[] args) {
                  
          // 新建鏈表并加入元素
                  List<Member> members = new ArrayList<Member>();
                  members.add(
          new Member("01""王五"20));
                  members.add(
          new Member("02""劉六"26));
                  members.add(
          new Member("03""錢一"24));
                  members.add(
          new Member("04""趙二"21));
                  members.add(
          new Member("05""李四"29));
                  members.add(
          new Member("06""張三"28));
                  members.add(
          new Member("07""張七"25));

                  
          // 輸出排序后的鏈表
                  System.out.println("Original Data: ");
                  
          for (Member member : members) {
                      System.out.println(
          "  " + member.getName() + ":" + member.getAge());
                  }

                  
          // 按名字排序
                  Collections.sort(members, new CompareNamePinyin());
                  System.out.println(
          "Sort by Name: ");
                  
          // 輸出排序后的鏈表
                  for (Member member : members) {
                      System.out.println(
          "  " + member.getName() + ":" + member.getAge());
                  }

                  
          // 按年齡排序
                  Collections.sort(members, new CompareAge());
                  System.out.println(
          "Sort by Age:");
                  
          // 輸出排序后的鏈表
                  for (Member member : members) {
                      System.out.println(
          "  " + member.getName() + ":" + member.getAge());
                  }
              }

          }
          輸出結果:
          Original Data: 
            王五:
          20
            劉六:
          26
            錢一:
          24
            趙二:
          21
            李四:
          29
            張三:
          28
            張七:
          25
          Sort by Name: 
            李四:
          29
            劉六:
          26
            錢一:
          24
            王五:
          20
            張七:
          25
            張三:
          28
            趙二:
          21
          Sort by Age:
            王五:
          20
            趙二:
          21
            錢一:
          24
            張七:
          25
            劉六:
          26
            張三:
          28
            李四:
          29

          源代碼(包含Jar包),可直接由eclipse導入

          參考:
          1、中文排序 - 漢語拼音
          2、用匿名類實現Comparator實現鏈表排序的例子
          posted on 2007-12-19 16:07 CoderDream 閱讀(1702) 評論(0)  編輯  收藏 所屬分類: 經驗點滴

          <2007年12月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          常用鏈接

          留言簿(9)

          我參與的團隊

          隨筆分類(245)

          隨筆檔案(239)

          文章分類(3)

          文章檔案(3)

          收藏夾(576)

          友情鏈接

          搜索

          •  

          積分與排名

          • 積分 - 458389
          • 排名 - 114

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宣汉县| 华容县| 永清县| 福州市| 博客| 前郭尔| 五家渠市| 玉溪市| 天峻县| 江城| 南川市| 枣阳市| 寿阳县| 土默特右旗| 吕梁市| 潼南县| 三江| 金门县| 巴塘县| 潞城市| 临朐县| 泊头市| 永定县| 合川市| 玉门市| 盱眙县| 当阳市| 奎屯市| 漾濞| 河西区| 辽中县| 台中县| 阿巴嘎旗| 营口市| 乌拉特后旗| 诸城市| 张家口市| 内丘县| 师宗县| 桓台县| 右玉县|