主要方法体:
int ret = 0; Object a,b; try { Field f = a.getClass().getDeclaredField(field); f.setAccessible(true); Class<?> type = f.getType(); if (type == int.class) { ret = ((Integer) f.getInt(a)).compareTo((Integer) f .getInt(b)); } } //SortListUtil.sort(list, "id", SortListUtil.DESC); int ret = 0; try { Method m = a.getClass().getMethod(method, null); m.setAccessible(true); Class<?> type = m.getReturnType(); if (type == int.class) { ret = ((Integer) m.invoke(a, null)) .compareTo((Integer) m.invoke(b, null)); } } //SortListUtil.sortByMethod(list, "getId", null);
需求:
做一个对象排序的功能,需要按不同规则排序
Compareable接口和Comparator接口都是用来实现集合排序的,只是Comparable是在集合内部定义的方法实现的排序,而Comparator是在集合外部实现的排序 ,所以,如想实现排序,就需在集合外定义Comparator接口的方法或在集合内实现Compareable接口的方法。
Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作);
Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
可以说一个是类自已完成比较,一个是外部程序实现比较的差别而已。
Compareable接口
要对对象进行比较大小则需要实现Compareable接口
Compareable接口只有一个方法int compareTo(Object obj) 实现了此接口的 对象列表(或数组) 可以通过Collections.sort(Arrays.sort)来排序
class Paper implements Comparable<Paper> { String pcolor; public Paper(String pcolor) { this.pcolor=pcolor; } public int compareTo(Object o)//public int compareTo(Paper o) { if (o instanceof TestComparable) { Paper p=(Paper)o; //未使用泛型不转换的话不能访问pcolor int cmp=this.pcolor.compareTo(p.pcolor); return cmp; } } //重载toString方法定义输出 public String toString() { return this.pcolor; } } public class TestComparable { public static void main(String []args) { Paper p1=new Paper("red"); Paper p2=new Paper("blue"); Paper p3=new Paper("green"); List l=new LinkedList(); l.add(p1); l.add(p2); l.add(p3); Collections.sort(l); System.out.println(l); } }
Comparator接口:
在Comparator接口里,只有一个方法是需要实现的:
int compare(Object o1,Object o2);
提示: 如果o1小于o2,返回一个负数;如果o1大于o2,返回一个正数;如果他们相等,则返回0;
注意: compare 方法一定要是对称的,意思是compare(a,b) 返回的结果要跟compare(b,a) 相反。相反的结果意味着,要么返回的值带有不同的正负号,要么都是0。注意,象compare(a,b) 返回4而compare(b,a) 返回-2这样的情况是合法的。方法里常常可能抛出异常,在这个方法里抛出异常也要是对称的。如果调用compare(a,b) 时抛出了一个ClassCastException 异常,那么调用compare(b,a) 时也必须抛出一个ClassCastException 异常。
另外: 任何你准备重用的Comparator 都必须是可序列化的。TreeSet 和TreeMap 类存储Comparator 以便进行比较,因此为了这两个类能被序列化,它们使用的Comparator 也必须能被序列化。
Comparator 接口,通常被Collections.sort 方法使用,它是JAVA中需要了解的一个很重要的部分
public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } get.set... @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } }
新建一个实现Comparator的实现类PersonComparator:
import java.util.Comparator; public class PersonComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { if (p1.getAge() > p2.getAge()) { return 1; } else if (p1.getAge() < p2.getAge()) { return -1; } return 0; } }
CompareTest做测试:
import java.util.Arrays; public class CompareTest { public static void main(String[] args) { Person[] persons = { new Person("P1", 60), new Person("P2", 20), new Person("P3", 40) }; System.out.println(Arrays.toString(persons)); Arrays.sort(persons, new PersonComparator()); System.out.println(Arrays.toString(persons)); } }
public class RunDemoMain { public static void main(String[] args) { List<DataBean> dataBeans = new ArrayList<DataBean>(); dataBeans.add(new DataBean(23, "b", "w")); dataBeans.add(new DataBean(34, "e", "w")); dataBeans.add(new DataBean(12, "s", "w")); dataBeans.add(new DataBean(10, "c", "w")); System.out.println("==========排序前=========="); for (DataBean bean : dataBeans) { System.out.println(bean); } System.out.println("==========排序后=========="); Collections.sort(dataBeans, new DemoComparator()); for (DataBean bean : dataBeans) { System.out.println(bean); } } }
参考:
http://kentkwan.iteye.com/blog/739505
http://baomw.iteye.com/blog/197905
实际项目应用:
if(hotelForm.get("ascOrDesc").equals("ASC")){ Collections.sort(list, new MyComparator.HotelComparator()); }else{ Collections.sort(list, new MyComparator.HotelComparator()); Collections.reverse(list); }
public class MyComparator { public static class HotelComparator implements Comparator { public int compare(Object first, Object second) { return ((Hotel)first).getHotelNameEn().compareToIgnoreCase(((Hotel)second).getHotelNameEn()); } } }
公用排序方法:
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; /** * 通用工具类之按对象中某属性排序 * @author 李坤 * 交流博客:http://blog.csdn.net/lk_blog */ public class SortListUtil { public static final String DESC = "desc"; public static final String ASC = "asc"; /** * 对list中的元素按升序排列. * * @param list * 排序集合 * @param field * 排序字段 * @return */ public static List<?> sort(List<?> list, final String field) { return sort(list, field, null); } /** * 对list中的元素进行排序. * * @param list * 排序集合 * @param field * 排序字段 * @param sort * 排序方式: SortList.DESC(降序) SortList.ASC(升序). * @return */ @SuppressWarnings("unchecked") public static List<?> sort(List<?> list, final String field, final String sort) { Collections.sort(list, new Comparator() { public int compare(Object a, Object b) { int ret = 0; try { Field f = a.getClass().getDeclaredField(field); f.setAccessible(true); Class<?> type = f.getType(); if (type == int.class) { ret = ((Integer) f.getInt(a)).compareTo((Integer) f .getInt(b)); } else if (type == double.class) { ret = ((Double) f.getDouble(a)).compareTo((Double) f .getDouble(b)); } else if (type == long.class) { ret = ((Long) f.getLong(a)).compareTo((Long) f .getLong(b)); } else if (type == float.class) { ret = ((Float) f.getFloat(a)).compareTo((Float) f .getFloat(b)); } else if (type == Date.class) { ret = ((Date) f.get(a)).compareTo((Date) f.get(b)); } else if (isImplementsOf(type, Comparable.class)) { ret = ((Comparable) f.get(a)).compareTo((Comparable) f .get(b)); } else { ret = String.valueOf(f.get(a)).compareTo( String.valueOf(f.get(b))); } } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } if (sort != null && sort.toLowerCase().equals(DESC)) { return -ret; } else { return ret; } } }); return list; } /** * 对list中的元素按fields和sorts进行排序, * fields[i]指定排序字段,sorts[i]指定排序方式.如果sorts[i]为空则默认按升序排列. * * @param list * @param fields * @param sorts * @return */ @SuppressWarnings("unchecked") public static List<?> sort(List<?> list, String[] fields, String[] sorts) { if (fields != null && fields.length > 0) { for (int i = fields.length - 1; i >= 0; i--) { final String field = fields[i]; String tmpSort = ASC; if (sorts != null && sorts.length > i && sorts[i] != null) { tmpSort = sorts[i]; } final String sort = tmpSort; Collections.sort(list, new Comparator() { public int compare(Object a, Object b) { int ret = 0; try { Field f = a.getClass().getDeclaredField(field); f.setAccessible(true); Class<?> type = f.getType(); if (type == int.class) { ret = ((Integer) f.getInt(a)) .compareTo((Integer) f.getInt(b)); } else if (type == double.class) { ret = ((Double) f.getDouble(a)) .compareTo((Double) f.getDouble(b)); } else if (type == long.class) { ret = ((Long) f.getLong(a)).compareTo((Long) f .getLong(b)); } else if (type == float.class) { ret = ((Float) f.getFloat(a)) .compareTo((Float) f.getFloat(b)); } else if (type == Date.class) { ret = ((Date) f.get(a)).compareTo((Date) f .get(b)); } else if (isImplementsOf(type, Comparable.class)) { ret = ((Comparable) f.get(a)) .compareTo((Comparable) f.get(b)); } else { ret = String.valueOf(f.get(a)).compareTo( String.valueOf(f.get(b))); } } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } if (sort != null && sort.toLowerCase().equals(DESC)) { return -ret; } else { return ret; } } }); } } return list; } /** * 默认按正序排列 * * @param list * @param method * @return */ public static List<?> sortByMethod(List<?> list, final String method) { return sortByMethod(list, method, null); } @SuppressWarnings("unchecked") public static List<?> sortByMethod(List<?> list, final String method, final String sort) { Collections.sort(list, new Comparator() { public int compare(Object a, Object b) { int ret = 0; try { Method m = a.getClass().getMethod(method, null); m.setAccessible(true); Class<?> type = m.getReturnType(); if (type == int.class) { ret = ((Integer) m.invoke(a, null)) .compareTo((Integer) m.invoke(b, null)); } else if (type == double.class) { ret = ((Double) m.invoke(a, null)).compareTo((Double) m .invoke(b, null)); } else if (type == long.class) { ret = ((Long) m.invoke(a, null)).compareTo((Long) m .invoke(b, null)); } else if (type == float.class) { ret = ((Float) m.invoke(a, null)).compareTo((Float) m .invoke(b, null)); } else if (type == Date.class) { ret = ((Date) m.invoke(a, null)).compareTo((Date) m .invoke(b, null)); } else if (isImplementsOf(type, Comparable.class)) { ret = ((Comparable) m.invoke(a, null)) .compareTo((Comparable) m.invoke(b, null)); } else { ret = String.valueOf(m.invoke(a, null)).compareTo( String.valueOf(m.invoke(b, null))); } if (isImplementsOf(type, Comparable.class)) { ret = ((Comparable) m.invoke(a, null)) .compareTo((Comparable) m.invoke(b, null)); } else { ret = String.valueOf(m.invoke(a, null)).compareTo( String.valueOf(m.invoke(b, null))); } } catch (NoSuchMethodException ne) { System.out.println(ne); } catch (IllegalAccessException ie) { System.out.println(ie); } catch (InvocationTargetException it) { System.out.println(it); } if (sort != null && sort.toLowerCase().equals(DESC)) { return -ret; } else { return ret; } } }); return list; } @SuppressWarnings("unchecked") public static List<?> sortByMethod(List<?> list, final String methods[], final String sorts[]) { if (methods != null && methods.length > 0) { for (int i = methods.length - 1; i >= 0; i--) { final String method = methods[i]; String tmpSort = ASC; if (sorts != null && sorts.length > i && sorts[i] != null) { tmpSort = sorts[i]; } final String sort = tmpSort; Collections.sort(list, new Comparator() { public int compare(Object a, Object b) { int ret = 0; try { Method m = a.getClass().getMethod(method, null); m.setAccessible(true); Class<?> type = m.getReturnType(); if (type == int.class) { ret = ((Integer) m.invoke(a, null)) .compareTo((Integer) m.invoke(b, null)); } else if (type == double.class) { ret = ((Double) m.invoke(a, null)) .compareTo((Double) m.invoke(b, null)); } else if (type == long.class) { ret = ((Long) m.invoke(a, null)) .compareTo((Long) m.invoke(b, null)); } else if (type == float.class) { ret = ((Float) m.invoke(a, null)) .compareTo((Float) m.invoke(b, null)); } else if (type == Date.class) { ret = ((Date) m.invoke(a, null)) .compareTo((Date) m.invoke(b, null)); } else if (isImplementsOf(type, Comparable.class)) { ret = ((Comparable) m.invoke(a, null)) .compareTo((Comparable) m.invoke(b, null)); } else { ret = String.valueOf(m.invoke(a, null)) .compareTo( String.valueOf(m .invoke(b, null))); } } catch (NoSuchMethodException ne) { System.out.println(ne); } catch (IllegalAccessException ie) { System.out.println(ie); } catch (InvocationTargetException it) { System.out.println(it); } if (sort != null && sort.toLowerCase().equals(DESC)) { return -ret; } else { return ret; } } }); } } return list; } /** * 判断对象实现的所有接口中是否包含szInterface * * @param clazz * @param szInterface * @return */ public static boolean isImplementsOf(Class<?> clazz, Class<?> szInterface) { boolean flag = false; Class<?>[] face = clazz.getInterfaces(); for (Class<?> c : face) { if (c == szInterface) { flag = true; } else { flag = isImplementsOf(c, szInterface); } } if (!flag && null != clazz.getSuperclass()) { return isImplementsOf(clazz.getSuperclass(), szInterface); } return flag; } public static void main(String[] args) throws Exception { List<Student> list = new ArrayList<Student>(); list.add(new Student(3, "b", 1, new Date(11110000))); list.add(new Student(1, "c", 3, new Date(44440000))); list.add(new Student(2, "a", 2, new Date(22210000))); list.add(new Student(4, "a", 11, new Date(33330000))); System.out.println("-------原来序列-------------------"); for (Student stu : list) { System.out.println(stu.toString()); } // 按age正序排序,注意结果排完后是1,2,3,11. 不是1,11,2,3(如果是String类型正序排序是这样) SortListUtil.sort(list, "age", null); System.out.println("---------测试Integer和正序,按age正序排序-----------------"); for (Student stu : list) { System.out.println(stu.toString()); } // 按id倒序 SortListUtil.sort(list, "id", SortListUtil.DESC); System.out.println("--------测试int和倒序,按id倒序------------------"); for (Student stu : list) { System.out.println(stu.toString()); } // 先按name正序排序,再按id正序排序 SortListUtil.sort(list, new String[] { "name", "id" }, new String[] {}); System.out .println("---------测试多个排序字段,先按name正序,name相同时再按id正序-----------------"); for (Student stu : list) { System.out.println(stu.toString()); } // 先按name正序排序,再按id倒序排序 SortListUtil.sort(list, new String[] { "name", "id" }, new String[] { SortListUtil.ASC, SortListUtil.DESC }); System.out .println("---------测试多个排序字段,先按name正序,name相同时再按id倒序-----------------"); for (Student stu : list) { System.out.println(stu.toString()); } // 按birthday排序 SortListUtil.sort(list, "birthday"); System.out .println("---------测试实现了Comparable接口的对象排序,按birthday正序-----------------"); for (Student stu : list) { System.out.println(stu.toString()); } // sortByMethod SortListUtil.sortByMethod(list, "getId", null); System.out .println("---------测试sortByMethod,按getId方法正序-----------------"); for (Student stu : list) { System.out.println(stu.toString()); } } }
排序方法来源:http://blog.csdn.net/lk_blog/article/details/12804873