1. 程式人生 > >java list按照元素物件的指定多個欄位屬性進行排序

java list按照元素物件的指定多個欄位屬性進行排序

ListUtils.Java---功能類

 http://blog.csdn.net/jiangyu1013/article/details/53894218

[java] view plain copy

 

 

  1. package com.enable.common.utils;  
  2.   
  3. import java.lang.reflect.Field;  
  4. import java.text.NumberFormat;  
  5. import java.util.Collections;  
  6. import java.util.Comparator;  
  7. import java.util.Date;  
  8. import java.util.List;  
  9.   
  10. /** 
  11.  * @author yinaibang 
  12.  * 在資料庫中查出來的列表中,往往需要對不同的欄位重新排序。 一般的做法都是使用排序的欄位,重新到資料庫中查詢。 
  13.  * 如果不到資料庫查詢,直接在第一次查出來的list中排序,無疑會提高系統的效能。 下面就寫一個通用的方法,對list排序, 
  14.  *  
  15.  * 至少需要滿足以下5點: 
  16.  *  
  17.  * ①.list元素物件型別任意  
  18.  *      ---->使用泛型解決 
  19.  *  
  20.  * ②.可以按照list元素物件的任意多個屬性進行排序,即可以同時指定多個屬性進行排序  
  21.  *      --->使用java的可變引數解決 
  22.  *  
  23.  * ③.list元素物件屬性的型別可以是數字(byte、short、int、long、float、double等,包括正數、負數、0)、字串(char、String)、日期(java.util.Date) 
  24.  *      --->對於數字:統一轉換為固定長度的字串解決,比如數字3和123,轉換為"003"和"123" ;再比如"-15"和"7"轉換為"-015"和"007"  
  25.  *      --->對於日期:可以先把日期轉化為long型別的數字,數字的解決方法如上 
  26.  *  
  27.  * ④.list元素物件的屬性可以沒有相應的getter和setter方法  
  28.  *      --->可以使用java反射進行獲取private和protected修飾的屬性值 
  29.  *  
  30.  * ⑤.list元素物件的物件的每個屬性都可以指定是升序還是降序 
  31.  *      -->使用2個重寫的方法(一個方法滿足所有屬性都按照升序(降序),另外一個方法滿足每個屬性都能指定是升序(降序)) 
  32.  *  
  33.  * 
  34.  */  
  35. public class ListUtils {  
  36.     /** 
  37.      * 對list的元素按照多個屬性名稱排序, 
  38.      * list元素的屬性可以是數字(byte、short、int、long、float、double等,支援正數、負數、0)、char、String、java.util.Date 
  39.      *  
  40.      *  
  41.      * @param lsit 
  42.      * @param sortname 
  43.      *            list元素的屬性名稱 
  44.      * @param isAsc 
  45.      *            true升序,false降序 
  46.      */  
  47.     public static <E> void sort(List<E> list, final boolean isAsc, final String... sortnameArr) {  
  48.         Collections.sort(list, new Comparator<E>() {  
  49.   
  50.             public int compare(E a, E b) {  
  51.                 int ret = 0;  
  52.                 try {  
  53.                     for (int i = 0; i < sortnameArr.length; i++) {  
  54.                         ret = ListUtils.compareObject(sortnameArr[i], isAsc, a, b);  
  55.                         if (0 != ret) {  
  56.                             break;  
  57.                         }  
  58.                     }  
  59.                 } catch (Exception e) {  
  60.                     e.printStackTrace();  
  61.                 }  
  62.                 return ret;  
  63.             }  
  64.         });  
  65.     }  
  66.       
  67.     /** 
  68.      * 給list的每個屬性都指定是升序還是降序 
  69.      *  
  70.      * @param list 
  71.      * @param sortnameArr  引數陣列 
  72.      * @param typeArr      每個屬性對應的升降序陣列, true升序,false降序 
  73.      */  
  74.   
  75.     public static <E> void sort(List<E> list, final String[] sortnameArr, final boolean[] typeArr) {  
  76.         if (sortnameArr.length != typeArr.length) {  
  77.             throw new RuntimeException("屬性陣列元素個數和升降序陣列元素個數不相等");  
  78.         }  
  79.         Collections.sort(list, new Comparator<E>() {  
  80.             public int compare(E a, E b) {  
  81.                 int ret = 0;  
  82.                 try {  
  83.                     for (int i = 0; i < sortnameArr.length; i++) {  
  84.                         ret = ListUtils.compareObject(sortnameArr[i], typeArr[i], a, b);  
  85.                         if (0 != ret) {  
  86.                             break;  
  87.                         }  
  88.                     }  
  89.                 } catch (Exception e) {  
  90.                     e.printStackTrace();  
  91.                 }  
  92.                 return ret;  
  93.             }  
  94.         });  
  95.     }  
  96.   
  97.     /** 
  98.      * 對2個物件按照指定屬性名稱進行排序 
  99.      *  
  100.      * @param sortname 
  101.      *            屬性名稱 
  102.      * @param isAsc 
  103.      *            true升序,false降序 
  104.      * @param a 
  105.      * @param b 
  106.      * @return 
  107.      * @throws Exception 
  108.      */  
  109.     private static <E> int compareObject(final String sortname, final boolean isAsc, E a, E b) throws Exception {  
  110.         int ret;  
  111.         Object value1 = ListUtils.forceGetFieldValue(a, sortname);  
  112.         Object value2 = ListUtils.forceGetFieldValue(b, sortname);  
  113.         String str1 = value1.toString();  
  114.         String str2 = value2.toString();  
  115.         if (value1 instanceof Number && value2 instanceof Number) {  
  116.             int maxlen = Math.max(str1.length(), str2.length());  
  117.             str1 = ListUtils.addZero2Str((Number) value1, maxlen);  
  118.             str2 = ListUtils.addZero2Str((Number) value2, maxlen);  
  119.         } else if (value1 instanceof Date && value2 instanceof Date) {  
  120.             long time1 = ((Date) value1).getTime();  
  121.             long time2 = ((Date) value2).getTime();  
  122.             int maxlen = Long.toString(Math.max(time1, time2)).length();  
  123.             str1 = ListUtils.addZero2Str(time1, maxlen);  
  124.             str2 = ListUtils.addZero2Str(time2, maxlen);  
  125.         }  
  126.         if (isAsc) {  
  127.             ret = str1.compareTo(str2);  
  128.         } else {  
  129.             ret = str2.compareTo(str1);  
  130.         }  
  131.         return ret;  
  132.     }  
  133.   
  134.     /** 
  135.      * 給數字物件按照指定長度在左側補0. 
  136.      *  
  137.      * 使用案例: addZero2Str(11,4) 返回 "0011", addZero2Str(-18,6)返回 "-000018" 
  138.      *  
  139.      * @param numObj 
  140.      *            數字物件 
  141.      * @param length 
  142.      *            指定的長度 
  143.      * @return 
  144.      */  
  145.     public static String addZero2Str(Number numObj, int length) {  
  146.         NumberFormat nf = NumberFormat.getInstance();  
  147.         // 設定是否使用分組  
  148.         nf.setGroupingUsed(false);  
  149.         // 設定最大整數位數  
  150.         nf.setMaximumIntegerDigits(length);  
  151.         // 設定最小整數位數  
  152.         nf.setMinimumIntegerDigits(length);  
  153.         return nf.format(numObj);  
  154.     }  
  155.   
  156.     /** 
  157.      * 獲取指定物件的指定屬性值(去除private,protected的限制) 
  158.      *  
  159.      * @param obj 
  160.      *            屬性名稱所在的物件 
  161.      * @param fieldName 
  162.      *            屬性名稱 
  163.      * @return 
  164.      * @throws Exception 
  165.      */  
  166.     public static Object forceGetFieldValue(Object obj, String fieldName) throws Exception {  
  167.         Field field = obj.getClass().getDeclaredField(fieldName);  
  168.         Object object = null;  
  169.         boolean accessible = field.isAccessible();  
  170.         if (!accessible) {  
  171.             // 如果是private,protected修飾的屬性,需要修改為可以訪問的  
  172.             field.setAccessible(true);  
  173.             object = field.get(obj);  
  174.             // 還原private,protected屬性的訪問性質  
  175.             field.setAccessible(accessible);  
  176.             return object;  
  177.         }  
  178.         object = field.get(obj);  
  179.         return object;  
  180.     }  
  181. }  

 

 

UserInfo.java

 

[java] view plain copy

 

 

  1. package com;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5. /** 
  6.  *  
  7.  * @author yinaibang 
  8.  * 
  9.  */  
  10. public class UserInfo implements java.io.Serializable {  
  11.   
  12.     private static final long serialVersionUID = -3522051445403971732L;  
  13.   
  14.     private Integer userId;  
  15.     private String username;  
  16.     private Date birthDate;  
  17.     private Integer age;  
  18.     private float fRate;  
  19.     private char ch;  
  20.   
  21.     public Date getBirthDate() {  
  22.         return birthDate;  
  23.     }  
  24.   
  25.     public String getBirthDatestr() {  
  26.         SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");  
  27.         return formater.format(getBirthDate());  
  28.     }  
  29.   
  30.     public UserInfo(Integer userId, String username, Date birthDate, Integer age, float fRate, char ch) {  
  31.         super();  
  32.         this.userId = userId;  
  33.         this.username = username;  
  34.         this.birthDate = birthDate;  
  35.         this.age = age;  
  36.         this.fRate = fRate;  
  37.         this.ch = ch;  
  38.     }  
  39.   
  40.     @Override  
  41.     public String toString() {  
  42.         return "UserInfo [userId=" + userId + ", \tusername=" + username + ", \tbirthDate=" + getBirthDatestr()  
  43.                 + ", \tage=" + age + ", fRate=" + fRate + ", ch=" + ch + "]";  
  44.     }  
  45.   
  46. }  


 

 

 

Test.java---測試

 

[java] view plain copy

 

 

  1. package com;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. import com.enable.common.utils.ListUtils;  
  8.   
  9. /** 
  10.  *  
  11.  * @author yinaibang 
  12.  * 
  13.  */  
  14. public class Test {  
  15.   
  16.     public static void main(String[] args) throws Exception {  
  17.   
  18.         Test testObj = new Test();  
  19.   
  20.         List<UserInfo> list = new ArrayList<UserInfo>();  
  21.         // public UserInfo(Integer userId, String username, Date birthDate,Integer age, float fRate, char ch)  
  22.         SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");  
  23.         UserInfo user1 = new UserInfo(3, "bbb", formater.parse("1980-12-01"), 1, 1.2f, 'a');  
  24.         UserInfo user2 = new UserInfo(0, "126", formater.parse("1900-10-11"), 03, -3.6f, 'c');  
  25.         UserInfo user3 = new UserInfo(12, "5", formater.parse("1973-08-21"), 15, 9.32f, 'f');  
  26.         UserInfo user4 = new UserInfo(465, "1567", formater.parse("2012-01-26"), 20, 12.56f, '0');  
  27.         UserInfo user5 = new UserInfo(2006, "&4m", formater.parse("2010-05-08"), 100, 165.32f, '5');  
  28.         UserInfo user6 = new UserInfo(5487, "hf67", formater.parse("2016-12-30"), 103, 56.32f, 'm');  
  29.         UserInfo user7 = new UserInfo(5487,"jigg", formater.parse("2000-10-16"), 103, 56.32f, 'm');  
  30.         UserInfo user8 = new UserInfo(5487, "jigg", formater.parse("1987-07-25"), 103, 56.32f, 'm');  
  31.   
  32.         list.add(user1);  
  33.         list.add(user2);  
  34.         list.add(user3);  
  35.         list.add(user4);  
  36.         list.add(user5);  
  37.         list.add(user6);  
  38.         list.add(user7);  
  39.         list.add(user8);  
  40.   
  41.         System.out.println("\n-------原來序列-------------------");  
  42.         testObj.printfUserInfoList(list);  
  43.   
  44.         // 按userId升序、username降序、birthDate升序排序  
  45.         String [] sortNameArr = {"userId","username","birthDate"};  
  46.         boolean [] isAscArr = {true,false,true};  
  47.         ListUtils.sort(list,sortNameArr,isAscArr);  
  48.         System.out.println("\n--------按按userId升序、username降序、birthDate升序排序(如果userId相同,則按照username降序,如果username相同,則按照birthDate升序)------------------");  
  49.         testObj.printfUserInfoList(list);  
  50.           
  51.         // 按userId、username、birthDate都升序排序  
  52.         ListUtils.sort(list, true, "userId", "username","birthDate");  
  53.         System.out.println("\n--------按userId、username、birthDate排序(如果userId相同,則按照username升序,如果username相同,則按照birthDate升序)------------------");  
  54.         testObj.printfUserInfoList(list);  
  55.   
  56.         // 按userId、username都倒序排序  
  57.         ListUtils.sort(list, false, "userId", "username");  
  58.         System.out.println("\n--------按userId和username倒序(如果userId相同,則按照username倒序)------------------");  
  59.         testObj.printfUserInfoList(list);  
  60.   
  61.         // 按username、birthDate都升序排序  
  62.         ListUtils.sort(list, true, "username", "birthDate");  
  63.         System.out.println("\n---------按username、birthDate升序(如果username相同,則按照birthDate升序)-----------------");  
  64.         testObj.printfUserInfoList(list);  
  65.   
  66.         // 按birthDate倒序排序  
  67.         ListUtils.sort(list, false, "birthDate");  
  68.         System.out.println("\n---------按birthDate倒序-----------------");  
  69.         testObj.printfUserInfoList(list);  
  70.   
  71.         // 按fRate升序排序  
  72.         ListUtils.sort(list, true, "fRate");  
  73.         System.out.println("\n---------按fRate升序-----------------");  
  74.         testObj.printfUserInfoList(list);  
  75.   
  76.         // 按ch倒序排序  
  77.         ListUtils.sort(list, false, "ch");  
  78.         System.out.println("\n---------按ch倒序-----------------");  
  79.         testObj.printfUserInfoList(list);  
  80.   
  81.     }  
  82.   
  83.     private void printfUserInfoList(List<UserInfo> list) {  
  84.         for (UserInfo user : list) {  
  85.             System.out.println(user.toString());  
  86.         }  
  87.     }  
  88. }  

 

 

執行結果

 

[java] view plain copy

 

 

  1. -------原來序列-------------------  
  2. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  3. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  4. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  5. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  6. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  7. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  8. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  9. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  10.   
  11. --------按按userId升序、username降序、birthDate升序排序(如果userId相同,則按照username降序,如果username相同,則按照birthDate升序)------------------  
  12. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  13. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  14. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  15. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  16. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  17. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  18. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  19. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  20.   
  21. --------按userId、username、birthDate排序(如果userId相同,則按照username升序,如果username相同,則按照birthDate升序)------------------  
  22. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  23. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  24. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  25. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  26. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  27. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  28. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  29. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  30.   
  31. --------按userId和username倒序(如果userId相同,則按照username倒序)------------------  
  32. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  33. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  34. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  35. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  36. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  37. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  38. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  39. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  40.   
  41. ---------按username、birthDate升序(如果username相同,則按照birthDate升序)-----------------  
  42. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  43. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  44. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  45. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  46. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  47. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  48. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  49. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  50.   
  51. ---------按birthDate倒序-----------------  
  52. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  53. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  54. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  55. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  56. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  57. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  58. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  59. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  60.   
  61. ---------按fRate升序-----------------  
  62. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  63. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  64. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  65. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]  
  66. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  67. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  68. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  69. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  70.   
  71. ---------按ch倒序-----------------  
  72. UserInfo [userId=5487,  username=hf67,  birthDate=2016-12-30,   age=103, fRate=56.32, ch=m]  
  73. UserInfo [userId=5487,  username=jigg,  birthDate=2000-10-16,   age=103, fRate=56.32, ch=m]  
  74. UserInfo [userId=5487,  username=jigg,  birthDate=1987-07-25,   age=103, fRate=56.32, ch=m]  
  75. UserInfo [userId=12,    username=5,     birthDate=1973-08-21,   age=15, fRate=9.32, ch=f]  
  76. UserInfo [userId=0,     username=126,   birthDate=1900-10-11,   age=3, fRate=-3.6, ch=c]  
  77. UserInfo [userId=3,     username=bbb,   birthDate=1980-12-01,   age=1, fRate=1.2, ch=a]  
  78. UserInfo [userId=2006,  username=&4m,   birthDate=2010-05-08,   age=100, fRate=165.32, ch=5]  
  79. UserInfo [userId=465,   username=1567,  birthDate=2012-01-26,   age=20, fRate=12.56, ch=0]