Spring中如何使用Comparator接口

网友投稿 204 2022-10-18


Spring中如何使用Comparator接口

我们先来回顾下Comparator接口在我们日常开发中的作用,Comparator比较器接口可以将自身传递给排序方法(比如Collections.sort或Arrays.sort),以便对排序顺序进行精确控制。比如:

List 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 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(@NullablpVDHgmJuSIe Object o1, @Nullablehttp:// 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://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接口的详细内容,更多关于Spring 使用Comparator接口的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:一款真正可以操作的数据中心可视化管理软件
下一篇:荷兰警方警告 DDoS 出租客户停止或面临起诉
相关文章

 发表评论

暂时没有评论,来抢沙发吧~