OrderComparator 的排序逻辑
OrderComparator 实现了 Comparator 接口,重写
compare()
方法compare()
方法内部仅仅是调用了doCompare()
方法,因此doCompare()
方法的排序规则即为compare()
方法的排序规则接下来是对于
compare(o1,o2)
本身的讨论对于任何排序来说,我们假定只有唯一一条本质的排序规则:优先级(weight)高的排在前面。
而其它各种自定义的排序规则(比较器)被认为是该规则的具体化。例如,对数字的升序排序,可以认为是数值小的优先级高;对数字的降序排序,可以认为是数值大的优先级高。在当前的假设下,compare() 的设计者对方法的约定为:当 o1 的优先级比 o2 高时,compare(o1, o2) 的返回值为负;当 o1 的优先级比 o2 低时,compare(o1, o2) 的返回值为正。(充要条件,前推后,后推前)
最后回到
doCompare()
本身上来,实现逻辑为:- 如果是 PriorityOrder 类型,那么拥有更高的优先级(weight)
- 如果类型相同,那么 order 值越小,优先级(weight)越高。没有 order 值的按 order = Integer.MAX_VALUE 处理
public class OrderComparator implements Comparator<Object> {
public static final OrderComparator INSTANCE = new OrderComparator();
public Comparator<Object> withSourceProvider(OrderSourceProvider sourceProvider) {
return (o1, o2) -> doCompare(o1, o2, sourceProvider);
}
@Override
public int compare(@Nullable Object o1, @Nullable Object o2) {
return doCompare(o1, o2, null);
}
// 1. PriorityOrdered 比 Order 拥有更高的优先级 (o1拥有更高优先级, 但是doCompore(o1,o2)的返回值是-1)
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
boolean p1 = (o1 instanceof PriorityOrdered);
boolean p2 = (o2 instanceof PriorityOrdered);
if (p1 && !p2) {
return -1;
}else if (p2 && !p1) {
return 1;
}
int i1 = getOrder(o1, sourceProvider);
int i2 = getOrder(o2, sourceProvider);
return Integer.compare(i1, i2);
}
private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
Integer order = null;
if (obj != null && sourceProvider != null) {
Object orderSource = sourceProvider.getOrderSource(obj);
if (orderSource != null) {
if (orderSource.getClass().isArray()) {
for (Object source : ObjectUtils.toObjectArray(orderSource)) {
order = findOrder(source);
if (order != null) {
break;
}
}
}
else {
order = findOrder(orderSource);
}
}
}
return (order != null ? order : getOrder(obj));
}
protected int getOrder(@Nullable Object obj) {
if (obj != null) {
Integer order = findOrder(obj);
if (order != null) {
return order;
}
}
return Ordered.LOWEST_PRECEDENCE;
}
@Nullable
protected Integer findOrder(Object obj) {
return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}
@Nullable
public Integer getPriority(Object obj) {
return null;
}
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);
}
}
@FunctionalInterface
public interface OrderSourceProvider {
@Nullable
Object getOrderSource(Object obj);
}
}