要实现comparator的比较方法,首先需要集合外部定义comparator接口的方法,即实现类,然后在实现类中实现comparator接口的方法
Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。
public class CompareObject<T> implements Comparator<T> { /** * 设定任意属性 进行比较 */ private final List<String> BEAN_PROPERTIES = new ArrayList<String>(); private final static String _DESC = "DESC"; //private final static String BLANK = ""; public int compare(T o1, T o2) { if (o1 == null || o2 == null) { return 0; } // 属性 列表为空 将不处理 返回为对象一致 if (BEAN_PROPERTIES.isEmpty()) { return 0; } int rel = 0; try { for (String item : BEAN_PROPERTIES) { rel = compare(item, o1, o2); if (rel != 0) { break; } } } catch (Throwable ex) { Log.getLogger().error(ex); } return rel; } /** * 排序执行 * * @param item * @param o1 * @param o2 * @return * @throws IllegalArgumentException * @throws IllegalAccessException * @throws NoSuchFieldException */ protected int compare(String item, T o1, T o2) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException { Comparable obj1; Comparable obj2; String[] properties; String field; String sortString; sortString = null; int rel = 0; properties = item.split("[ ]+"); if (properties.length > 1) { sortString = properties[1].replaceAll("[ ]*", ""); } field = properties[0]; obj1 = getComparableProperty(o1, field); obj2 = getComparableProperty(o2, field); int cmtint = 1; if (sortString != null && _DESC.equalsIgnoreCase(sortString)) { cmtint *= -1; } if (obj1 == null && obj2 != null) { rel = -1 * cmtint; } else if (obj1 != null && obj2 == null) { rel = 1 * cmtint; } else if (obj1 != null && obj2 != null) { rel = obj1.compareTo(obj2) * cmtint; } return rel; } /** * 设定属性 * * @param property * @return */ public CompareObject<T> addProperty(String property) { BEAN_PROPERTIES.add(property); return this; } /** * 设定属性列表 * * @param properties * @return */ public CompareObject<T> addAllProperty(List<String> properties) { BEAN_PROPERTIES.addAll(properties); return this; } /** * 获取可比较属性 * * @param bean * @param property * @return * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */ protected Comparable getComparableProperty(T bean, String property) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field = bean.getClass().getDeclaredField(property); field.setAccessible(true); return (Comparable) field.get(bean); } }
用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
实例代码:
例子1:
// 创建一个用来装比较属性的容器 CompareObject<User> comparableTor = new CompareObject<User>(); // 创建需要填的的属性,放到属性容器中 List<String> sortChars = new ArrayList<String>(); sortChars.add("name"); // 将属性值传送人对应的属性容器中 comparableTor.addAllProperty(sortChars); Collections.sort(users,comparableTor);
例子2:
List<PickingListItem> itemlst = bill.getItems();//按照时间先进先出顺序排序 Collections.sort(itemlst, new Comparator<PickingListItem>() { public int compare(PickingListItem o1, PickingListItem o2) { int bincp = o1.getBinCode().compareTo(o2.getBinCode()); if (bincp == 0) { int macdcp = o1.getMaterialCode().compareTo(o2.getMaterialCode()); if (macdcp == 0) { int batchcp = o1.getBatch().compareTo(o2.getBatch()); return batchcp; } else { return macdcp; } } else { return bincp; } } });
Comparable和Comparator区别:
Comparable是排序接口,若一个类实现了Comparable接口(Enum 类就实现了这个接口),就意味着“该类支持排序”。而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
Comparator升序降序实现
1) 用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
2) Comparable改变对象自身。
①如果要按照升序排序,
则o1 小于o2,返回-1(负数),相等返回0,o1大于o2返回1(正数)
有如下两种实现方法:
Comparator comparator = new Comparator() { @Override public int compare(Integer x, Integer y) { //方法一 // return (x==y)?0:(x<y)?1:(-1); //方法二 return (x==y)?0:(x-y); } }
②如果要按照降序排序
则o1 小于o2,返回1(正数),相等返回0,o1大于o2返回-1(负数)
有如下两种实现方法:
Comparator comparator = new Comparator() { @Override public int compare(Integer x, Integer y) { //方法一 // return (x==y)?0:(y<x)?1:(-1); //方法二 return (x==y)?0:(y-x); } };
Collection 和Collections
java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。(详细见:网上摘录Java中常见数据结构:list与map )
Collection
├List
│ ├LinkedList
│ ├ArrayList
│ └Vector
│ └Stack
└Set
java.util.Collections 是一个包装类(工具类/帮助类)。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架。