正文
如果filterOrder一样如何排序?
我们看看Integer
的compare
方法具体的逻辑
如果x==y,则返回0,x
看到这里,我们得出这样的结论,如果filterOrder
一样,则Collections.sort(list);
排序时不交换位置,这按照ZuulFilter
默认加载顺序。那么,ZuulFilter的默认加载顺序是怎么样的?
它是通过getAllFilters
方法获取ZuulFilter
集合,该方法其实返回的是名称为filters
的ConcurrentHashMap
的values
,即返回Set
集合,是无序的。
- 重要的事情说三遍:如果filterOrder一样,ZuulFilter是无序的。
- 重要的事情说三遍:如果filterOrder一样,ZuulFilter是无序的。
- 重要的事情说三遍:如果filterOrder一样,ZuulFilter是无序的。
所以,filterOrder切记不要定义相同的,不然可能会出现无法预知的执行结果。
两种排序方法
自定义排序其实有两种方法:
- 实现Comparable接口,重写compareTo方法,
- 实现Comparator接口,重写compare方法如果要使用
Collections.sort(list);
排序,它默认用的是第一种方法,上面的filterOrder
之所以可以排序,是因为Integer
实现了Comparable
接口,重写了compareTo
方法
如果想自己定义排序规则可以通过实现Comparator
接口,重写compare
方法。
Collections.sort(list,new Comparator<Integer>(){ @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } });
它的底层也是通过二分查找实现的
那么这两种方法有什么区别呢?
- Comparable接口位于java.lang包下,而Comparator接口位于java.util包下。
- Comparable接口是内部比较器,一个类如果想要使用Collections.sort(list) 方法进行排序,则需要实现该接口
- Comparator接口是外部比较器用于对那些没有实现Comparable接口或者对已经实现的Comparable中的排序规则不满意进行排序.无需改变类的结构,更加灵活。
彩蛋
zuul
中是通过filterOrder
参数的大小排序的,而在spring
中是通过@Order
注解排序的。
默认情况下,如果不指定value值,则value是Integer的最大值。
由于排序规则是value越小,则排在越靠前,所以如果不指定value值,则它排在最后。
spring
是通过OrderComparator
类排序的,它实现了Comparator
接口,它的doCompare
方法实现的排序。
最终也是调用Integer
类的compare
方法,该方法前面已经介绍过了。