Spring中的ComparableComparator和Comparators
备注此处的Comparators指的是Spring包下的:org.springframework.util.comparator.Comparators,因为JDK自带的java.util.Comparators它是不提供给外部访问的。
ComparableComparator
// @since 1.2.2 比较器,用于将可比较器适配比较器接口。 public class ComparableComparator<T extends Comparable<T>> implements Comparator<T> { // 实例 单例 这样子的话就可以当作Comparator来使用了 @SuppressWarnings("rawtypes") public static final ComparableComparator INSTANCE = new ComparableComparator(); @Override public int compare(T o1, T o2) { return o1.compareTo(o2); } }
这个适配类是Spring1.2.2就出来了,但是下面的工具:Comparators
可是Spring5.0才提供
Comparators
它是Spring5.0后提供的一个工具类,里面主要是提供了一些静态方法,来提供外部比较器
// @since 5.0 注意使用它和直接使用Comparator的区别是,它要求你比较的对象都实现了Comparable的 否则都是不适用的 public abstract class Comparators { // 自然排序~~~~ // Arrays.sort(people, Comparators.comparable()); 比如你这么用,是要求peple里面元素实现了Comparable接口的 否则报错 @SuppressWarnings("unchecked") public static <T> Comparator<T> comparable() { return ComparableComparator.INSTANCE; } // null放在最后 @SuppressWarnings("unchecked") public static <T> Comparator<T> nullsLow() { return NullSafeComparator.NULLS_LOW; } /// null放最后 并且我们还可以提供一个自定义的比较器 public static <T> Comparator<T> nullsLow(Comparator<T> comparator) { return new NullSafeComparator<>(comparator, true); } @SuppressWarnings("unchecked") public static <T> Comparator<T> nullsHigh() { return NullSafeComparator.NULLS_HIGH; } public static <T> Comparator<T> nullsHigh(Comparator<T> comparator) { return new NullSafeComparator<>(comparator, false); } }
OrderComparator
使用OrderComparator来比较2个对象的排序顺序。注意它用于Spring用来比较实现了Ordered接口的对象。
注意它@since 07.04.2003出现得非常早,所以这个类并不支持@Order注解的排序~~~
但是,PriorityOrdered接口它也是支持的,虽然它Spring2.5才出现。
另外,它是一个Comparator,所以它可以作为自定义比较器放在数组、集合里排序。形如;
public class OrderComparator implements Comparator<Object> { ... public static void sort(List<?> list) { if (list.size() > 1) { list.sort(INSTANCE); } } public static void sort(Object[] array) { if (array.length > 1) { Arrays.sort(array, INSTANCE); } } public static void sortIfNecessary(Object value) { if (value instanceof Object[]) { sort((Object[]) value); } else if (value instanceof List) { sort((List<?>) value); } } }
AnnotationAwareOrderComparator
AnnotationAwareOrderComparator继承自OrderComparator
其可以同时处理对象实现Ordered接口或@Order注解。
显然它增强了排序能力,不仅支持Ordered接口,还支持到了@Order注解。
@Order注解@since 2.0,AnnotationAwareOrderComparator它@since 2.0.1,几乎同时出现的
它提供了两个静态方法,使用非常广泛,方便我们对数组、即可记性排序:
public class AnnotationAwareOrderComparator extends OrderComparator { /** * 用来检查实现Ordered接口、@Order和@Priority注解 */ protected Integer findOrder(Object obj) { // 检查常规的Ordered接口,通过子类重写的getOrder方法返回顺序值 Integer order = super.findOrder(obj); if (order != null) { return order; } // 检查实现@Order和@Priority注解 if (obj instanceof Class) { // 在类上检查@Order和@Priority注解,并找出顺序值 return OrderUtils.getOrder((Class<?>) obj); } else if (obj instanceof Method) { // 在方法上检查@Order注解,并找出顺序值 Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class); if (ann != null) { return ann.value(); } } else if (obj instanceof AnnotatedElement) { // 在注解中找@Order注解,并找出顺序值 Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class); if (ann != null) { return ann.value(); } } else if (obj != null) { order = OrderUtils.getOrder(obj.getClass()); if (order == null && obj instanceof DecoratingProxy) { order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass()); } } return order; } // ================================================================== // 注意此处和上面的区别,它用的是自己的instance public static void sort(List<?> list) { if (list.size() > 1) { list.sort(INSTANCE); } } */ public static void sort(Object[] array) { if (array.length > 1) { Arrays.sort(array, INSTANCE); } } public static void sortIfNecessary(Object value) { if (value instanceof Object[]) { sort((Object[]) value); } else if (value instanceof List) { sort((List<?>) value); } } }
OrderUtils
最后介绍这个工具类,它是Spring4.1后提出的。它支持注解@Order和javax.annotation.Priority也是被支持的,因此它的getOrder()方法就是获取order值了。
需要注意的是:先找@Order,若没有再去找@Priority,都没标注就返回默认值
该工具类并不支持Ordered接口的方式~~~
总结
对象排序或许是平时我们开发中都忽略的一块小知识点,我本人而言,每次使用都需要自己单元测试一番,生怕顺序弄反了。因此对此部分内容作一个记录,希望成为永久的记忆~~~