publicclassTestComparable{ publicstaticvoidmain(String[] args){ User u1 = new User("caililiang1",20,"hubei1"); User u2 = new User("caililiang2",30,"hubei2"); User u3 = new User("caililiang3",25,"hubei3"); User u4 = new User("caililiang4",28,"hubei4"); User u5 = new User("caililiang5",23,"hubei5");
List<User> list = new ArrayList<User>(); list.add(u1); list.add(u2); list.add(u3); list.add(u4); list.add(u5);
for(int i=0;i<list.size();i++){ User u =list.get(i); System.out.println(u.getName()+"--->"+u.getAge()); } System.out.println("排序后---------------------"); //在此处打上断点,方便进行调试 Collections.sort(list); for(int i=0;i<list.size();i++){ User u =list.get(i); System.out.println(u.getName()+"--->"+u.getAge()); } } }
1.3 Collections类中的泛型方法sort()
java
1 2 3 4 5 6 7
// 此处 <T extends Comparable<? super T>> 的意思是: // 1.<T extends Comparable>表示比较对象的类必须是Comparable 的子类。 // 2.Comparable<? super T>表示是Comparable实现类及以上。 publicstatic <T extends Comparable<? super T>> voidsort(List<T> list){ //调用List接口中的sort()方法 list.sort(null); }
1.4 List接口中的默认方法sort()
java
1 2 3 4 5 6 7 8 9 10 11
// 由于本例中采用的是ArrayList集合,ArrayList集合对List接口中的sort()方法进行了重写, // 因此实际在DeBug的过程中会执行ArrayLIst类中的sort()方法 defaultvoidsort(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); } }
staticvoidsort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen){ assert a != null && lo >= 0 && lo <= hi && hi <= a.length; //nRemaining表示没有排序的对象个数,方法执行前,如果这个数小于2,就不需要排序了。 //如果2<= nRemaining <=32,即MIN_MERGE的初始值,表示需要排序的数组是小数组 //可以使用mini-TimSort方法进行排序,否则需要使用归并排序。 int nRemaining = hi - lo; if (nRemaining < 2) return; // Arrays of size 0 and 1 are always sorted
// If array is small, do a "mini-TimSort" with no merges if (nRemaining < MIN_MERGE) { //调用重写的compareTo()方法 int initRunLen = countRunAndMakeAscending(a, lo, hi); //只看这一句 binarySort(a, lo, hi, lo + initRunLen); return; } ...... }
//这里才是真正的调用compareTo()方法对当前对象进行比较 privatestaticintcountRunAndMakeAscending(Object[] a, int lo, int hi){ assert lo < hi; int runHi = lo + 1; if (runHi == hi) return1;
// Find end of run, and reverse range if descending if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // 降序排列 while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0) runHi++; reverseRange(a, lo, runHi); } else {// 升序排列 while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0) runHi++; }
return runHi - lo; }
//这里才是真正的进行排序。 privatestaticvoidbinarySort(Object[] a, int lo, int hi, int start){ assert lo <= start && start <= hi; if (start == lo) start++; for ( ; start < hi; start++) { Comparable pivot = (Comparable) 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; if (pivot.compareTo(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) { case2: a[left + 2] = a[left + 1]; case1: a[left + 1] = a[left]; break; default: System.arraycopy(a, left, a, left + 1, n); } a[left] = pivot; } }
publicclassTestComparator{ publicstaticvoidmain(String[] args){ People u1 = new People("caililiang1",20,"hubei1"); People u2 = new People("caililiang2",30,"hubei2"); People u3 = new People("caililiang3",25,"hubei3"); People u4 = new People("caililiang4",28,"hubei4"); People u5 = new People("caililiang5",23,"hubei5");
List<People> list = new ArrayList<People>(); list.add(u1); list.add(u2); list.add(u3); list.add(u4); list.add(u5);
for(int i=0;i<list.size();i++){ People u =list.get(i); System.out.println(u.getName()+"--->"+u.getAge()); }
System.out.println("排序后---------------------");
Collections.sort(list,new PeopleComparator());
for(int i=0;i<list.size();i++){ People u =list.get(i); System.out.println(u.getName()+"--->"+u.getAge()); } } }
static <T> voidsort(T[] a, int lo, int hi, Comparator<? super T> c, T[] work, int workBase, int workLen){ assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
int nRemaining = hi - lo; if (nRemaining < 2) return; // Arrays of size 0 and 1 are always sorted
// If array is small, do a "mini-TimSort" with no merges if (nRemaining < MIN_MERGE) { int initRunLen = countRunAndMakeAscending(a, lo, hi, c); binarySort(a, lo, hi, lo + initRunLen, c); return; } privatestatic <T> voidbinarySort(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; 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) { case2: a[left + 2] = a[left + 1]; case1: a[left + 1] = a[left]; break; default: System.arraycopy(a, left, a, left + 1, n); } a[left] = pivot; } }