1.例子
以List<Entry<String, Double>>为例
要求:按照Double由大到小来排序
Map<String, Double> map = new HashMap<String, Double>();
map.put("test2",2D);
map.put("test3",3D);
map.put("test1",1D);
List<Entry<String, Double>> mapList = new ArrayList<Entry<String, Double>>();
mapList.addAll(map.entrySet());
System.out.println(mapList);
Collections.sort(mapList, new Comparator<Entry<String, Double>>() {
public int compare(Entry<String, Double> entry1, Entry<String, Double> entry2) {
Double d1 = entry1.getValue();
Double d2 =entry2.getValue();
return d2.compareTo(d1);
}
});
System.out.println(mapList);
}
打印结果为
[test2=2.0, test3=3.0, test1=1.0]
[test3=3.0, test2=2.0, test1=1.0]
主要需要注意下重写的compare方法的返回值,先看下Comparator.compare方法的调用的地方:
private static <T> void binarySort(T[] a, int lo, int hi, int start,
Comparator<? super T> c) {
assert lo <= start && start <= hi;
if (start == lo)
start++;
for ( ; start < hi; start++) {
T pivot = a[start];
// Set left (and right) to the index where a[start] (pivot) belongs
int left = lo;
int right = start;
assert left <= right;
/*
* Invariants:
* pivot >= all in [lo, left).
* pivot < all in [right, start).
*/
while (left < right) {
int mid = (left + right) >>> 1;
//在compare结果小于0的时候,会将pivot值排到a[mid]之前
//反之,如果compare的结果大于等于0,会将pivot的值排到a[mid]之后
if (c.compare(pivot, a[mid]) < 0)
right = mid;
else
left = mid + 1;
}
assert left == right;
/*
* The invariants still hold: pivot >= all in [lo, left) and
* pivot < all in [left, start), so pivot belongs at left. Note
* that if there are elements equal to pivot, left points to the
* first slot after them -- that's why this sort is stable.
* Slide elements over to make room for pivot.
*/
int n = start - left; // The number of elements to move
// Switch is just an optimization for arraycopy in default case
switch (n) {
case 2: a[left + 2] = a[left + 1];
case 1: a[left + 1] = a[left];
break;
default: System.arraycopy(a, left, a, left + 1, n);
}
a[left] = pivot;
}
}
2.源码
从最开始的Collections的sort排序方法开始看
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
此方法直接调用了List接口的sort方法,从JDK1.8开始,接口已经可以写实现方法了。
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
其方法的本质还是调用了Arrays.sort(T[] a, Comparator<? super T> c)方法
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);