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 都必须是可序列化的。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());}// 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
- Compareable接口和Comparator + 公用排序方法
- Compareable接口和Comparator
- Java集合排序之compareTo&compare 接口 compareable & comparator
- compareTo&compare 接口 compareable & comparator
- 集合排序的两种方法Comparable接口和Comparator接口(比较器)
- 排序接口Comparable和Comparator的应用
- Arrays.sort排序方法以及Comparator和Comparable接口的作用
- 使用Comparator 接口 排序
- Comparator接口实现排序
- Java Comparable排序接口和Comparator比较器接口
- Java中comparable和comparator接口的排序原理
- java排序和Comparable,Comparator两个接口区别
- java用Comparable和Comparator接口进行排序
- Comparator和Comparable接口
- Comparable 和 Comparator接口
- Comparable和Comparator接口
- Comparator和Comparable接口
- Comparable和Comparator接口
- Oracle
- 二叉树的重建
- 博客第一天
- Hibernate缓存机制
- SourceTree使用
- Compareable接口和Comparator + 公用排序方法
- 设计模式学习笔记——组合(Composite)模式
- 润乾V5通过下拉日历传参改变查询语句中数据库名称字段
- php错误日志输出
- 数字字符串的格式化
- js创建对象
- 在Ubantu14.04下快速集成Mosquitto
- JS总结
- Android Stuido插件