小编给大家分享一下Spring中怎么使用Comparator接口,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
我们先来回顾下Comparator接口在我们日常开发中的作用,Comparator比较器接口可以将自身传递给排序方法(比如Collections.sort或Arrays.sort),以便对排序顺序进行精确控制。比如:
List<Integer> intList = Arrays.asList(2, 3, 1); Collections.sort(intList, (o1, o2) -> { return o2-o1; });
输出
[3, 2, 1]
Comparator可以用来控制某些数据结构(如sored sets 或sorted maps)的顺序,或者为没有自然顺序的对象集合提供顺序,比如:
public class Emp { private int empNo; private String eName; //省略getter setter @Override public String toString() { return "empno:\t"+empno+"\tename:\t"+ename; } } Comparator<Emp> comparator = (o1, o2) -> { return o1.getEmpno()-o2.getEmpno(); }; empList.sort(comparator);
从以上使用方法可以看出Comparator是策略模式的一个经典体现,在Spring中它为实现了Ordered接口的类写了一个比较器名叫OrderComparator,我们来看看它的compare方法:
@Override public int compare(@Nullable Object o1, @Nullable Object o2) { return doCompare(o1, o2, null); } private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) { //判断是否实现了PriorityOrdered接口 //o1为原先的后一个元素 //o2为原先的前一个元素 boolean p1 = (o1 instanceof PriorityOrdered); boolean p2 = (o2 instanceof PriorityOrdered); //p1实现了PriorityOrdered,但是p2没实现PriorityOrdered,则p1优先级更高 if (p1 && !p2) { ////小于0 表示逆序 o1排前 return -1; } else if (p2 && !p1) { //p2实现了PriorityOrdered,但是p1没实现PriorityOrdered,则p2优先级更高 //大于0 表示正序 o2排前 return 1; } int i1 = getOrder(o1, sourceProvider); int i2 = getOrder(o2, sourceProvider); return Integer.compare(i1, i2); } protected int getOrder(@Nullable Object obj) { if (obj != null) { Integer order = findOrder(obj); if (order != null) { return order; } } //Integer.MAX_VALUE代表最低优先级 return Ordered.LOWEST_PRECEDENCE; } @Nullable protected Integer findOrder(Object obj) { return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null); }
OrderComparator主要是通过实现Order接口方法getOrder返回的值来比较的,而通过注解Order比较的话是采用继承OrderComparator类的AnnotationAwareOrderComparator类来重载getOrder方法来实现:
@Override @Nullable protected Integer findOrder(Object obj) { // Check for regular Ordered interface //检查常规的Order接口 Integer order = super.findOrder(obj); if (order != null) { return order; } //检查@Order注解和@Priority注解 // Check for @Order and @Priority on various kinds of elements if (obj instanceof Class) { return OrderUtils.getOrder((Class<?>) obj); } else if (obj instanceof Method) { Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class); if (ann != null) { return ann.value(); } } else if (obj instanceof AnnotatedElement) { //AnnotatedElement代表在当前运行的java虚拟机中一个可以被注解的元素,这个接口允许通过反射读取元素上面的注解,这与我们之 前的理解是一致的 //https://www.yuque.com/cuihualong/javaseries/sh91es Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class); if (ann != null) { return ann.value(); } } else { order = OrderUtils.getOrder(obj.getClass()); if (order == null && obj instanceof DecoratingProxy) { order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass()); } } return order; }
这里顺便提下在SpringBoot中ConditionalOnBean,ConditionalOnProperty,ConditionalOnClass等注解实际上都采用了实现Order注解的方法来进行排序。这里我就截个图看下了:
Conditional注解中的OnClassCondition类就标了@Order注解
实现Comparator接口compare方法的时候主要是要注意以下几点(翻译自官方文档):
用中文简单来说就是在 JDK7 版本以上默认使用Timsort排序方法来实现,Comparator 比较器要满足自反性,传递性,反对称性,不然 Arrays.sort,Collections.sort有可能会报 IllegalArgumentException 异常。
以上是“Spring中怎么使用Comparator接口”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。