Java通用工具类之按对象属性排序工具

本工具类为按对象属性排序工具类,实现的功能:
1.按对象的一个属性和多个属性进行排序.
2.按对象属性正序和倒序排列.
3.完美支持int等基础类和Integer等包装类.
4.完美支持属性为实现了Comparable接口的类.
5.如果类不是java.lang中定义的基础类型也没有实现Comparable接口则转为String后进行排序.

实现思路:使用反射取得对象属性或对象方法的值从而解除对具体对象的依赖.

[java][/java] view plaincopy

  1. import java.lang.reflect.Field;
  2. import java.lang.reflect.InvocationTargetException;
  3. import java.lang.reflect.Method;
  4. import java.util.ArrayList;
  5. import java.util.Collections;
  6. import java.util.Comparator;
  7. import java.util.Date;
  8. import java.util.List;
  9. /**
  10.  * 通用工具类之按对象中某属性排序
  11.  * @author 李坤
  12.  * 交流博客:http://blog.csdn.net/lk_blog
  13.  */
  14. public class SortListUtil {
  15.     public static final String DESC = “desc”;
  16.     public static final String ASC = “asc”;
  17.     /**
  18.      * 对list中的元素按升序排列.
  19.      *
  20.      * @param list
  21.      *            排序集合
  22.      * @param field
  23.      *            排序字段
  24.      * @return
  25.      */
  26.     public static List<?> sort(List<?> list, final String field) {
  27.         return sort(list, field, null);
  28.     }
  29.     /**
  30.      * 对list中的元素进行排序.
  31.      *
  32.      * @param list
  33.      *            排序集合
  34.      * @param field
  35.      *            排序字段
  36.      * @param sort
  37.      *            排序方式: SortList.DESC(降序) SortList.ASC(升序).
  38.      * @return
  39.      */
  40.     @SuppressWarnings(“unchecked”)
  41.     public static List<?> sort(List<?> list, final String field,
  42.             final String sort) {
  43.         Collections.sort(list, new Comparator() {
  44.             public int compare(Object a, Object b) {
  45.                 int ret = 0;
  46.                 try {
  47.                     Field f = a.getClass().getDeclaredField(field);
  48.                     f.setAccessible(true);
  49.                     Class<?> type = f.getType();
  50.                     if (type == int.class) {
  51.                         ret = ((Integer) f.getInt(a)).compareTo((Integer) f
  52.                                 .getInt(b));
  53.                     } else if (type == double.class) {
  54.                         ret = ((Double) f.getDouble(a)).compareTo((Double) f
  55.                                 .getDouble(b));
  56.                     } else if (type == long.class) {
  57.                         ret = ((Long) f.getLong(a)).compareTo((Long) f
  58.                                 .getLong(b));
  59.                     } else if (type == float.class) {
  60.                         ret = ((Float) f.getFloat(a)).compareTo((Float) f
  61.                                 .getFloat(b));
  62.                     } else if (type == Date.class) {
  63.                         ret = ((Date) f.get(a)).compareTo((Date) f.get(b));
  64.                     } else if (isImplementsOf(type, Comparable.class)) {
  65.                         ret = ((Comparable) f.get(a)).compareTo((Comparable) f
  66.                                 .get(b));
  67.                     } else {
  68.                         ret = String.valueOf(f.get(a)).compareTo(
  69.                                 String.valueOf(f.get(b)));
  70.                     }
  71.                 } catch (SecurityException e) {
  72.                     e.printStackTrace();
  73.                 } catch (NoSuchFieldException e) {
  74.                     e.printStackTrace();
  75.                 } catch (IllegalArgumentException e) {
  76.                     e.printStackTrace();
  77.                 } catch (IllegalAccessException e) {
  78.                     e.printStackTrace();
  79.                 }
  80.                 if (sort != null && sort.toLowerCase().equals(DESC)) {
  81.                     return -ret;
  82.                 } else {
  83.                     return ret;
  84.                 }
  85.             }
  86.         });
  87.         return list;
  88.     }
  89.     /**
  90.      * 对list中的元素按fields和sorts进行排序,
  91.      * fields[i]指定排序字段,sorts[i]指定排序方式.如果sorts[i]为空则默认按升序排列.
  92.      *
  93.      * @param list
  94.      * @param fields
  95.      * @param sorts
  96.      * @return
  97.      */
  98.     @SuppressWarnings(“unchecked”)
  99.     public static List<?> sort(List<?> list, String[] fields, String[] sorts) {
  100.         if (fields != null && fields.length > 0) {
  101.             for (int i = fields.length – 1; i >= 0; i–) {
  102.                 final String field = fields[i];
  103.                 String tmpSort = ASC;
  104.                 if (sorts != null && sorts.length > i && sorts[i] != null) {
  105.                     tmpSort = sorts[i];
  106.                 }
  107.                 final String sort = tmpSort;
  108.                 Collections.sort(list, new Comparator() {
  109.                     public int compare(Object a, Object b) {
  110.                         int ret = 0;
  111.                         try {
  112.                             Field f = a.getClass().getDeclaredField(field);
  113.                             f.setAccessible(true);
  114.                             Class<?> type = f.getType();
  115.                             if (type == int.class) {
  116.                                 ret = ((Integer) f.getInt(a))
  117.                                         .compareTo((Integer) f.getInt(b));
  118.                             } else if (type == double.class) {
  119.                                 ret = ((Double) f.getDouble(a))
  120.                                         .compareTo((Double) f.getDouble(b));
  121.                             } else if (type == long.class) {
  122.                                 ret = ((Long) f.getLong(a)).compareTo((Long) f
  123.                                         .getLong(b));
  124.                             } else if (type == float.class) {
  125.                                 ret = ((Float) f.getFloat(a))
  126.                                         .compareTo((Float) f.getFloat(b));
  127.                             } else if (type == Date.class) {
  128.                                 ret = ((Date) f.get(a)).compareTo((Date) f
  129.                                         .get(b));
  130.                             } else if (isImplementsOf(type, Comparable.class)) {
  131.                                 ret = ((Comparable) f.get(a))
  132.                                         .compareTo((Comparable) f.get(b));
  133.                             } else {
  134.                                 ret = String.valueOf(f.get(a)).compareTo(
  135.                                         String.valueOf(f.get(b)));
  136.                             }
  137.                         } catch (SecurityException e) {
  138.                             e.printStackTrace();
  139.                         } catch (NoSuchFieldException e) {
  140.                             e.printStackTrace();
  141.                         } catch (IllegalArgumentException e) {
  142.                             e.printStackTrace();
  143.                         } catch (IllegalAccessException e) {
  144.                             e.printStackTrace();
  145.                         }
  146.                         if (sort != null && sort.toLowerCase().equals(DESC)) {
  147.                             return -ret;
  148.                         } else {
  149.                             return ret;
  150.                         }
  151.                     }
  152.                 });
  153.             }
  154.         }
  155.         return list;
  156.     }
  157.     /**
  158.      * 默认按正序排列
  159.      *
  160.      * @param list
  161.      * @param method
  162.      * @return
  163.      */
  164.     public static List<?> sortByMethod(List<?> list, final String method) {
  165.         return sortByMethod(list, method, null);
  166.     }
  167.     @SuppressWarnings(“unchecked”)
  168.     public static List<?> sortByMethod(List<?> list, final String method,
  169.             final String sort) {
  170.         Collections.sort(list, new Comparator() {
  171.             public int compare(Object a, Object b) {
  172.                 int ret = 0;
  173.                 try {
  174.                     Method m = a.getClass().getMethod(method, null);
  175.                     m.setAccessible(true);
  176.                     Class<?> type = m.getReturnType();
  177.                     if (type == int.class) {
  178.                         ret = ((Integer) m.invoke(a, null))
  179.                                 .compareTo((Integer) m.invoke(b, null));
  180.                     } else if (type == double.class) {
  181.                         ret = ((Double) m.invoke(a, null)).compareTo((Double) m
  182.                                 .invoke(b, null));
  183.                     } else if (type == long.class) {
  184.                         ret = ((Long) m.invoke(a, null)).compareTo((Long) m
  185.                                 .invoke(b, null));
  186.                     } else if (type == float.class) {
  187.                         ret = ((Float) m.invoke(a, null)).compareTo((Float) m
  188.                                 .invoke(b, null));
  189.                     } else if (type == Date.class) {
  190.                         ret = ((Date) m.invoke(a, null)).compareTo((Date) m
  191.                                 .invoke(b, null));
  192.                     } else if (isImplementsOf(type, Comparable.class)) {
  193.                         ret = ((Comparable) m.invoke(a, null))
  194.                                 .compareTo((Comparable) m.invoke(b, null));
  195.                     } else {
  196.                         ret = String.valueOf(m.invoke(a, null)).compareTo(
  197.                                 String.valueOf(m.invoke(b, null)));
  198.                     }
  199.                     if (isImplementsOf(type, Comparable.class)) {
  200.                         ret = ((Comparable) m.invoke(a, null))
  201.                                 .compareTo((Comparable) m.invoke(b, null));
  202.                     } else {
  203.                         ret = String.valueOf(m.invoke(a, null)).compareTo(
  204.                                 String.valueOf(m.invoke(b, null)));
  205.                     }
  206.                 } catch (NoSuchMethodException ne) {
  207.                     System.out.println(ne);
  208.                 } catch (IllegalAccessException ie) {
  209.                     System.out.println(ie);
  210.                 } catch (InvocationTargetException it) {
  211.                     System.out.println(it);
  212.                 }
  213.                 if (sort != null && sort.toLowerCase().equals(DESC)) {
  214.                     return -ret;
  215.                 } else {
  216.                     return ret;
  217.                 }
  218.             }
  219.         });
  220.         return list;
  221.     }
  222.     @SuppressWarnings(“unchecked”)
  223.     public static List<?> sortByMethod(List<?> list, final String methods[],
  224.             final String sorts[]) {
  225.         if (methods != null && methods.length > 0) {
  226.             for (int i = methods.length – 1; i >= 0; i–) {
  227.                 final String method = methods[i];
  228.                 String tmpSort = ASC;
  229.                 if (sorts != null && sorts.length > i && sorts[i] != null) {
  230.                     tmpSort = sorts[i];
  231.                 }
  232.                 final String sort = tmpSort;
  233.                 Collections.sort(list, new Comparator() {
  234.                     public int compare(Object a, Object b) {
  235.                         int ret = 0;
  236.                         try {
  237.                             Method m = a.getClass().getMethod(method, null);
  238.                             m.setAccessible(true);
  239.                             Class<?> type = m.getReturnType();
  240.                             if (type == int.class) {
  241.                                 ret = ((Integer) m.invoke(a, null))
  242.                                         .compareTo((Integer) m.invoke(b, null));
  243.                             } else if (type == double.class) {
  244.                                 ret = ((Double) m.invoke(a, null))
  245.                                         .compareTo((Double) m.invoke(b, null));
  246.                             } else if (type == long.class) {
  247.                                 ret = ((Long) m.invoke(a, null))
  248.                                         .compareTo((Long) m.invoke(b, null));
  249.                             } else if (type == float.class) {
  250.                                 ret = ((Float) m.invoke(a, null))
  251.                                         .compareTo((Float) m.invoke(b, null));
  252.                             } else if (type == Date.class) {
  253.                                 ret = ((Date) m.invoke(a, null))
  254.                                         .compareTo((Date) m.invoke(b, null));
  255.                             } else if (isImplementsOf(type, Comparable.class)) {
  256.                                 ret = ((Comparable) m.invoke(a, null))
  257.                                         .compareTo((Comparable) m.invoke(b,
  258.                                                 null));
  259.                             } else {
  260.                                 ret = String.valueOf(m.invoke(a, null))
  261.                                         .compareTo(
  262.                                                 String.valueOf(m
  263.                                                         .invoke(b, null)));
  264.                             }
  265.                         } catch (NoSuchMethodException ne) {
  266.                             System.out.println(ne);
  267.                         } catch (IllegalAccessException ie) {
  268.                             System.out.println(ie);
  269.                         } catch (InvocationTargetException it) {
  270.                             System.out.println(it);
  271.                         }
  272.                         if (sort != null && sort.toLowerCase().equals(DESC)) {
  273.                             return -ret;
  274.                         } else {
  275.                             return ret;
  276.                         }
  277.                     }
  278.                 });
  279.             }
  280.         }
  281.         return list;
  282.     }
  283.     /**
  284.      * 判断对象实现的所有接口中是否包含szInterface
  285.      *
  286.      * @param clazz
  287.      * @param szInterface
  288.      * @return
  289.      */
  290.     public static boolean isImplementsOf(Class<?> clazz, Class<?> szInterface) {
  291.         boolean flag = false;
  292.         Class<?>[] face = clazz.getInterfaces();
  293.         for (Class<?> c : face) {
  294.             if (c == szInterface) {
  295.                 flag = true;
  296.             } else {
  297.                 flag = isImplementsOf(c, szInterface);
  298.             }
  299.         }
  300.         if (!flag && null != clazz.getSuperclass()) {
  301.             return isImplementsOf(clazz.getSuperclass(), szInterface);
  302.         }
  303.         return flag;
  304.     }
  305.     public static void main(String[] args) throws Exception {
  306.         List<Student> list = new ArrayList<Student>();
  307.         list.add(new Student(3, “b”, 1, new Date(11110000)));
  308.         list.add(new Student(1, “c”, 3, new Date(44440000)));
  309.         list.add(new Student(2, “a”, 2, new Date(22210000)));
  310.         list.add(new Student(4, “a”, 11, new Date(33330000)));
  311.         System.out.println(“——-原来序列——————-“);
  312.         for (Student stu : list) {
  313.             System.out.println(stu.toString());
  314.         }
  315.         // 按age正序排序,注意结果排完后是1,2,3,11. 不是1,11,2,3(如果是String类型正序排序是这样)
  316.         SortListUtil.sort(list, “age”, null);
  317.         System.out.println(“———测试Integer和正序,按age正序排序—————–“);
  318.         for (Student stu : list) {
  319.             System.out.println(stu.toString());
  320.         }
  321.         // 按id倒序
  322.         SortListUtil.sort(list, “id”, SortListUtil.DESC);
  323.         System.out.println(“——–测试int和倒序,按id倒序——————“);
  324.         for (Student stu : list) {
  325.             System.out.println(stu.toString());
  326.         }
  327.         // 先按name正序排序,再按id正序排序
  328.         SortListUtil.sort(list, new String[] { “name”, “id” }, new String[] {});
  329.         System.out
  330.                 .println(“———测试多个排序字段,先按name正序,name相同时再按id正序—————–“);
  331.         for (Student stu : list) {
  332.             System.out.println(stu.toString());
  333.         }
  334.         // 先按name正序排序,再按id倒序排序
  335.         SortListUtil.sort(list, new String[] { “name”, “id” }, new String[] {
  336.                 SortListUtil.ASC, SortListUtil.DESC });
  337.         System.out
  338.                 .println(“———测试多个排序字段,先按name正序,name相同时再按id倒序—————–“);
  339.         for (Student stu : list) {
  340.             System.out.println(stu.toString());
  341.         }
  342.         // 按birthday排序
  343.         SortListUtil.sort(list, “birthday”);
  344.         System.out
  345.                 .println(“———测试实现了Comparable接口的对象排序,按birthday正序—————–“);
  346.         for (Student stu : list) {
  347.             System.out.println(stu.toString());
  348.         }
  349.         // sortByMethod
  350.         SortListUtil.sortByMethod(list, “getId”, null);
  351.         System.out
  352.                 .println(“———测试sortByMethod,按getId方法正序—————–“);
  353.         for (Student stu : list) {
  354.             System.out.println(stu.toString());
  355.         }
  356.     }
  357. }

测试执行效果:

 


Studeng.java:

[java][/java] view plaincopy

  1. import java.util.*;
  2. public class Student{
  3.     private int id;
  4.     private String name;
  5.     private Integer age;
  6.     private Date birthday;
  7.     public Student(int id, String name, Integer age, Date birthday) {
  8.         super();
  9.         this.id = id;
  10.         this.name = name;
  11.         this.age = age;
  12.         this.birthday = birthday;
  13.     }
  14.     public int getId() {
  15.         return id;
  16.     }
  17.     public void setId(int id) {
  18.         this.id = id;
  19.     }
  20.     public String getName() {
  21.         return name;
  22.     }
  23.     public void setName(String name) {
  24.         this.name = name;
  25.     }
  26.     public Integer getAge() {
  27.         return age;
  28.     }
  29.     public void setAge(Integer age) {
  30.         this.age = age;
  31.     }
  32.     public Date getBirthday() {
  33.         return birthday;
  34.     }
  35.     public void setBirthday(Date birthday) {
  36.         this.birthday = birthday;
  37.     }
  38.     @Override
  39.     public String toString() {
  40.         return “Student [id=” + id + “, name=” + name + “, age=” + age
  41.                 + “, birthday=” + birthday + “]”;
  42.     }
  43. }

 

 

 

 

以下关于Comparable和Comparator的基础知识摘自博客:http://uule.iteye.com/blog/766688

1.Comparable接口是在java.lang类中的,而Comparator接口是在java.util类中的。
2.Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

用自定义类实现 Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定。

而Comparator比较灵活,它没有和任何类绑定,实现它的自定义类仅仅定义了一种排序方式或排序规则。不言而喻,这种方式比较灵活。我们的要排序的类可以分别和多个实现 Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。Comparable——“静态绑定排序”,Comparator——“动态绑定排序”。

 

限于本人水平有限,很多地方写的并不完美,希望大家不吝赐教.不足之处欢迎留言交流,希望在和大家的交流中得到提高.

标签