源码片段5:mergeSort(Object[]src , Object[]dst , int low , int high , int off)
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
int length = high - low;
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
int destLow  = low;
int destHigh = high;
low  += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(Object[] x, int a, int b) {
Object t = x[a];
x[a] = x[b];
x[b] = t;
}
  仔细阅读代码可以发现排序是分段递归回调的方式来排序(注意中间的low和high两个参数的变化),每次如果分段的大小大于INSERTIONSORT_THRESHOLD(定义为7)的时候,则再分段,前一段和后一段,然后分开的两段再调用递推,递推后再回归排序,若发现中间分隔的位置两个数据是有序,则认为两段是完全有序的,若不是,那么再将两段做一次排序,此时排序很好排序了,因为两个块是排序排好的,所以不需要两次循环,只需要循环扫描下去,两个数组按照顺序向下走,分别对比出小值写入数组,较大者暂时不写入数组与另一个数组的下一个值进行对比,后一截数据(源码中是通过越界来判定的)写入到尾巴当中:
  for(int i = destLow, p = low, q = mid; i < destHigh; i++)
  {
  if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
  dest[i] = src[p++];
  else
  dest[i] = src[q++];
  }
  这段对两个有序数组的排序是很经典的写法,主要是if语句的浓缩,不然代码会写得很长。
  注意:这里的代码排序中使用了强制类型转换为Comparable来调用内部的comareTo方法,所以如果你的类没有implements Comparable那么在Collections.sort(List<T>list)时编译时会报错上面已经说到,在调用Arrays.sort(Object []t)时,编译时并不会报错,但是运行时会报错为:java.lang.ClassCastExceptionXXXDO cannot be cast to java.lang.Comparable
  排序部分我们再看看其重载的mergeSort方法,是传入了自定义的Comparator的方法
  源码片段6: mergeSort(Object[]src,Object[]dst,int low,int high,intoff,Comparator c)
private static void mergeSort(Object[] src,
Object[] dest,
int low, int high, int off,
Comparator c) {
int length = high - low;
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
int destLow  = low;
int destHigh = high;
low  += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off, c);
mergeSort(dest, src, mid, high, -off, c);
if (c.compare(src[mid-1], src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
  可以发现算法和上一个方法完全一样,的区别是排序时使用的compare变成了传入的comparator了,其余的没有任何区别。
  大概清楚了,此时发现java提供的排序还是比较高效的,大多数情况下你不需要自己去写排序算法,后我们再看看TreeSet中的在add的时候如何实现排序的,也是分别传入了comparator和没有传入,我们跟着源码里面,可以看到传入了comparator将这个属性设置给了TreeSet里面定义的一个TreeeMap,而TreeMap中的一个属性设置了这个Comparator:
  源码片段7:TreeSet以及TreeMap设置Comparator的构造方法
  public TreeSet(Comparator<? super E> comparator) {
  this(new TreeMap<E,Object>(comparator));
  }
  TreeSet(NavigableMap<E,Object> m) {
  this.m = m;
  }
  public TreeMap(Comparator<? super K> comparator) {
  this.comparator = comparator;
  }
  当然没有传入这个Comparator的时候自然没有设置到TreeMap中了,那么我们来看看TreeMap的add方法:
  源码片段8:TreeSet#add(E e)
  public boolean add(E e) {
  return m.put(e,PRESENT)==null;
  }
  这个m是什么呢?其实通过源码片段7可以看出,m是开始实例化的一个TreeMap,那么我们需要看TreeMap的put方法
  代码片段9:TreeMap#put(K key , V value)
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
root = new Entry<K,V>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<K,V>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
  这里判定了是否存在Comparator进行不同方式来写入不同的位置,并没有重载方法,所以实现上也不一定有什么非要如何做,只需要保证代码可读性很好好,一切为它服务,否则那些过多的设计是属于过度设计,当然并不是说代码设计不重要,但是这些需要适可而止;另外TreeSet里面对于其他的方法也会做排序处理,我们这里仅仅是用add方法来做一个例子而已。
  相信你对java的排序有了一些了解,也许本文说了一堆废话,因为本文不是在说排序算法,我们只是告诉你java是如何排序的,你在大部分情况下无需自己写排序算法来完成排序导致一些不必要的bug,而且效率未必有java本身提供的排序算法高效。