java list按照元素对象的指定多个字段属性进行排序

Posted tian830937

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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]  
技术分享
 
1
0




以上是关于java list按照元素对象的指定多个字段属性进行排序的主要内容,如果未能解决你的问题,请参考以下文章

Java关于list集合根据集合元素对象的某个或多个属性进行排序的工具类

Java中List对象集合按照对象某一属性字段排序

java 中 List<T>如何按照T中的一个字段排序?

java中如何将多个list集合对象拼接成一个集合对象

list中如何为一个对象附多个值

java List按照对象的属性进行分组