Compareable接口和Comparator + 公用排序方法

来源:互联网 发布:su for mac 教学视频 编辑:程序博客网 时间:2024/05/22 11:58

主要方法体:

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 都必须是可序列化的。TreeSetTreeMap 类存储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());}// sortByMethodSortListUtil.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

 

 

0 0
原创粉丝点击