深入理解java中Arrays.sort()的用法
Java的Arrays類中有一個(gè)sort()方法,該方法是Arrays類的靜態(tài)方法,在需要對(duì)數(shù)組進(jìn)行排序時(shí),非常的好用。
但是sort()的參數(shù)有好幾種,基本上是大同小異,下面是以int型數(shù)組為例的Arrays.sort()的典型用法
import java.util.Arrays;import java.util.Comparator;/** * Arrays.sort()排序 */public class SortTest{ public static void main(String []args) { int[] ints=new int[]{2,324,4,57,1}; System.out.println('增序排序后順序'); Arrays.sort(ints); for (int i=0;i<ints.length;i++) { System.out.print(ints[i]+' '); } System.out.println('n減序排序后順序'); //要實(shí)現(xiàn)減序排序,得通過(guò)包裝類型數(shù)組,基本類型數(shù)組是不行滴 Integer[] integers=new Integer[]{2,324,4,4,6,1}; Arrays.sort(integers, new Comparator<Integer>() { /* * 此處與c++的比較函數(shù)構(gòu)成不一致 * c++返回bool型,而Java返回的為int型 * 當(dāng)返回值>0時(shí) * 進(jìn)行交換,即排序(源碼實(shí)現(xiàn)為兩樞軸快速排序) */ public int compare(Integer o1, Integer o2) {return o2-o1; } public boolean equals(Object obj) {return false; } }); for (Integer integer:integers) { System.out.print(integer+' '); } System.out.println('n對(duì)部分排序后順序'); int[] ints2=new int[]{212,43,2,324,4,4,57,1}; //對(duì)數(shù)組的[2,6)位進(jìn)行排序 Arrays.sort(ints2,2,6); for (int i=0;i<ints2.length;i++) { System.out.print(ints2[i]+' '); } }}
排序結(jié)果如下
增序排序后順序1 2 4 57 324減序排序后順序324 6 4 4 2 1對(duì)部分排序后順序212 43 2 4 4 324 57 1
打開(kāi)Arrays.sort()源碼,還是以int型為例,其他類型也是大同小異
public static void sort(int[] a) { DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); } public static void sort(int[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); }
從源碼中發(fā)現(xiàn),兩種參數(shù)類型的sort方法都調(diào)用了 DualPivotQuicksort.sort()方法繼續(xù)跟蹤源碼
static void sort(int[] a, int left, int right, int[] work, int workBase, int workLen) { // Use Quicksort on small arrays if (right - left < QUICKSORT_THRESHOLD) { sort(a, left, right, true); return; } /* * Index run[i] is the start of i-th run * (ascending or descending sequence). */ int[] run = new int[MAX_RUN_COUNT + 1]; int count = 0; run[0] = left; // Check if the array is nearly sorted for (int k = left; k < right; run[count] = k) { if (a[k] < a[k + 1]) { // ascendingwhile (++k <= right && a[k - 1] <= a[k]); } else if (a[k] > a[k + 1]) { // descendingwhile (++k <= right && a[k - 1] >= a[k]);for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { int t = a[lo]; a[lo] = a[hi]; a[hi] = t;} } else { // equalfor (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) { if (--m == 0) { sort(a, left, right, true); return; }} } /* * The array is not highly structured, * use Quicksort instead of merge sort. */ if (++count == MAX_RUN_COUNT) {sort(a, left, right, true);return; } } // Check special cases // Implementation note: variable 'right' is increased by 1. if (run[count] == right++) { // The last run contains one element run[++count] = right; } else if (count == 1) { // The array is already sorted return; } // Determine alternation base for merge byte odd = 0; for (int n = 1; (n <<= 1) < count; odd ^= 1); // Use or create temporary array b for merging int[] b; // temp array; alternates with a int ao, bo; // array offsets from ’left’ int blen = right - left; // space needed for b if (work == null || workLen < blen || workBase + blen > work.length) { work = new int[blen]; workBase = 0; } if (odd == 0) { System.arraycopy(a, left, work, workBase, blen); b = a; bo = 0; a = work; ao = workBase - left; } else { b = work; ao = 0; bo = workBase - left; } // Merging for (int last; count > 1; count = last) { for (int k = (last = 0) + 2; k <= count; k += 2) {int hi = run[k], mi = run[k - 1];for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { b[i + bo] = a[p++ + ao]; } else { b[i + bo] = a[q++ + ao]; }}run[++last] = hi; } if ((count & 1) != 0) {for (int i = right, lo = run[count - 1]; --i >= lo; b[i + bo] = a[i + ao]);run[++last] = right; } int[] t = a; a = b; b = t; int o = ao; ao = bo; bo = o; } }
結(jié)合文檔以及源代碼,我們發(fā)現(xiàn),jdk中的Arrays.sort()的實(shí)現(xiàn)是通過(guò)所謂的雙軸快排的算法
/** * This class implements the Dual-Pivot Quicksort algorithm by * Vladimir Yaroslavskiy, Jon Bentley, and Josh Bloch. The algorithm * offers O(n log(n)) performance on many data sets that cause other * quicksorts to degrade to quadratic performance, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * All exposed methods are package-private, designed to be invoked * from public methods (in class Arrays) after performing any * necessary array bounds checks and expanding parameters into the * required forms. * * @author Vladimir Yaroslavskiy * @author Jon Bentley * @author Josh Bloch * * @version 2011.02.11 m765.827.12i:57pm * @since 1.7 */
Java1.8的快排是一種雙軸快排,顧名思義:雙軸快排是基于兩個(gè)軸來(lái)進(jìn)行比較,跟普通的選擇一個(gè)點(diǎn)來(lái)作為軸點(diǎn)的快排是有很大的區(qū)別的,雙軸排序利用了區(qū)間相鄰的特性,對(duì)原本的快排進(jìn)行了效率上的提高,很大程度上是利用了數(shù)學(xué)的一些特性。。。。。嗯。。。反正很高深的樣子
算法步驟
1.對(duì)于很小的數(shù)組(長(zhǎng)度小于27),會(huì)使用插入排序。2.選擇兩個(gè)點(diǎn)P1,P2作為軸心,比如我們可以使用第一個(gè)元素和最后一個(gè)元素。3.P1必須比P2要小,否則將這兩個(gè)元素交換,現(xiàn)在將整個(gè)數(shù)組分為四部分:(1)第一部分:比P1小的元素。(2)第二部分:比P1大但是比P2小的元素。(3)第三部分:比P2大的元素。(4)第四部分:尚未比較的部分。在開(kāi)始比較前,除了軸點(diǎn),其余元素幾乎都在第四部分,直到比較完之后第四部分沒(méi)有元素。4.從第四部分選出一個(gè)元素a[K],與兩個(gè)軸心比較,然后放到第一二三部分中的一個(gè)。5.移動(dòng)L,K,G指向。6.重復(fù) 4 5 步,直到第四部分沒(méi)有元素。7.將P1與第一部分的最后一個(gè)元素交換。將P2與第三部分的第一個(gè)元素交換。8.遞歸的將第一二三部分排序。
疑問(wèn):為啥不用泛型
到此這篇關(guān)于深入理解java中Arrays.sort()的用法的文章就介紹到這了,更多相關(guān)java Arrays.sort()內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. python共軛梯度法特征值迭代次數(shù)討論2. 利用FastReport傳遞圖片參數(shù)在報(bào)表上展示簽名信息的實(shí)現(xiàn)方法3. H5頁(yè)面使用audio標(biāo)簽播放音頻4. ASP.NET MVC視圖頁(yè)使用jQuery傳遞異步數(shù)據(jù)的幾種方式詳解5. CSS3使用過(guò)度動(dòng)畫和緩動(dòng)效果案例講解6. ASP.NET MVC通過(guò)勾選checkbox更改select的內(nèi)容7. react axios 跨域訪問(wèn)一個(gè)或多個(gè)域名問(wèn)題8. 詳解php如何合并身份證正反面圖片為一張圖片9. AJAX實(shí)現(xiàn)省市縣三級(jí)聯(lián)動(dòng)效果10. XHTML 1.0:標(biāo)記新的開(kāi)端
