Collections.sort分析
2016-04-10 22:58
239 查看
今天同学问我Collections.sort()如何实现,可惜早已忘记,回来赶紧翻代码。
String比较方法:
意思是:把无序集合变为有序集合;集合中所有元素必须实现Comparable接口;此外,如果集合中元素类型不同在调用compareTo方法时会抛出ClassCastException异常;如果在排序时向集合中添加元素,则报ConcurrentModificationException错误。
意思是:根据指定comparator来对集合进行排序;集合中所有元素根据指定的comparator来进行排序。
查看排序方法:
测试类
public static void main(String[] args) { List<String> strs1 = new ArrayList<>(); strs1.add("wrh"); strs1.add("swl"); strs1.add("zc"); Collections.sort(strs1); for (String str : strs1) { System.out.println(str); } }
String比较方法:
public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }
代码实现
public static <T extends Comparable<? super T>> void sort(List<T> list) { list.sort(null); }
方法1:
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list). This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort. The specified list must be modifiable, but need not be resizable.
意思是:把无序集合变为有序集合;集合中所有元素必须实现Comparable接口;此外,如果集合中元素类型不同在调用compareTo方法时会抛出ClassCastException异常;如果在排序时向集合中添加元素,则报ConcurrentModificationException错误。
public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); }
方法2:
Sorts the specified list according to the order induced by the specified comparator. All elements in the list must be mutually comparable using the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the list). This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort. The specified list must be modifiable, but need not be resizable.
意思是:根据指定comparator来对集合进行排序;集合中所有元素根据指定的comparator来进行排序。
list.sort方法
sort方法中调用的是list对象中的sort方法;我们以ArrayList方法中的sort方法。public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c);//排序是对数组进行操作的 if (modCount != expectedModCount) {//如果在排序时向集合中添加元素,抛出异常 throw new ConcurrentModificationException(); } modCount++; }
Arrays.sort方法
public static <T> void sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) { if (c == null) {//如果没有比较器 sort(a, fromIndex, toIndex); } else { rangeCheck(a.length, fromIndex, toIndex);//边界检测 if (LegacyMergeSort.userRequested)//根据配置选择排序方法 legacyMergeSort(a, fromIndex, toIndex, c); else TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0); } }
1.legacyMergeSort方法
private static <T> void legacyMergeSort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) { T[] aux = copyOfRange(a, fromIndex, toIndex);//首先复制数组 if (c==null)//是否有比较器 mergeSort(aux, a, fromIndex, toIndex, -fromIndex); else mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c); }
查看排序方法:
private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off, Comparator c) { int length = high - low; //当数组长度小于7时取出最大值放在最左边 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; } //大于7使用归并排序 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; } //把src数组合并到dest数组中 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++]; } }
2.TimSort.sort方法
TimSort 是一个归并排序做了大量优化的版本。对归并排序排在已经反向排好序的输入时表现O(n^2)的特点做了特别优化。对已经正向排好序的输入减少回溯。static <T> void sort(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; } /** * March over the array once, left to right, finding natural runs, * extending short natural runs to minRun elements, and merging runs * to maintain stack invariant. */ TimSort<T> ts = new TimSort<>(a, c, work, workBase, workLen); int minRun = minRunLength(nRemaining); do { // Identify next run int runLen = countRunAndMakeAscending(a, lo, hi, c); // If run is short, extend to min(minRun, nRemaining) if (runLen < minRun) { int force = nRemaining <= minRun ? nRemaining : minRun; binarySort(a, lo, lo + force, lo + runLen, c); runLen = force; } // Push run onto pending-run stack, and maybe merge ts.pushRun(lo, runLen); ts.mergeCollapse(); // Advance to find next run lo += runLen; nRemaining -= runLen; } while (nRemaining != 0); // Merge all remaining runs to complete sort assert lo == hi; ts.mergeForceCollapse(); assert ts.stackSize == 1; }
相关文章推荐
- C#.Net ArrayList的使用方法
- VBS ArrayList Class vbs中的数组类
- C#中Arraylist的sort函数用法实例分析
- C#中ArrayList的使用方法
- C#中Array与ArrayList用法及转换的方法
- C#生成随机ArrayList的方法
- c# ArrayList的使用方法小总结
- PHP实现C#山寨ArrayList的方法
- PowerShell中使用ArrayList实现数组插入、删除、添加例子
- 在JavaScript中构建ArrayList示例代码
- js实现ArrayList功能附实例代码
- 2种Java删除ArrayList中的重复元素的方法
- java arrayList遍历的四种方法及Java中ArrayList类的用法
- Java ArrayList.toArray(T[]) 方法的参数类型是 T 而不是 E的原因分析
- Java ArrayList 数组之间相互转换
- java使用listIterator逆序arraylist示例分享
- Java中的Vector和ArrayList区别及比较
- Java中ArrayList类的使用方法
- java中ArrayList 、LinkList的区别分析
- 浅析java中ArrayList与Vector的区别以及HashMap与Hashtable的区别