深入理解java中Arrays.sort()的用法
Java的Arrays類中有一個sort()方法,該方法是Arrays類的靜態(tài)方法,在需要對數(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減序排序后順序");
//要實現(xiàn)減序排序,得通過包裝類型數(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時
* 進行交換,即排序(源碼實現(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對部分排序后順序");
int[] ints2=new int[]{212,43,2,324,4,4,57,1};
//對數(shù)組的[2,6)位進行排序
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
對部分排序后順序
212 43 2 4 4 324 57 1
打開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]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++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 { // equal
for (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()的實現(xiàn)是通過所謂的雙軸快排的算法
/** * 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:5\7pm * @since 1.7 */
Java1.8的快排是一種雙軸快排,顧名思義:雙軸快排是基于兩個軸來進行比較,跟普通的選擇一個點來作為軸點的快排是有很大的區(qū)別的,雙軸排序利用了區(qū)間相鄰的特性,對原本的快排進行了效率上的提高,很大程度上是利用了數(shù)學(xué)的一些特性。。。。。嗯。。。反正很高深的樣子
算法步驟
1.對于很小的數(shù)組(長度小于27),會使用插入排序。
2.選擇兩個點P1,P2作為軸心,比如我們可以使用第一個元素和最后一個元素。
3.P1必須比P2要小,否則將這兩個元素交換,現(xiàn)在將整個數(shù)組分為四部分:
(1)第一部分:比P1小的元素。
(2)第二部分:比P1大但是比P2小的元素。
(3)第三部分:比P2大的元素。
(4)第四部分:尚未比較的部分。
在開始比較前,除了軸點,其余元素幾乎都在第四部分,直到比較完之后第四部分沒有元素。
4.從第四部分選出一個元素a[K],與兩個軸心比較,然后放到第一二三部分中的一個。
5.移動L,K,G指向。
6.重復(fù) 4 5 步,直到第四部分沒有元素。
7.將P1與第一部分的最后一個元素交換。將P2與第三部分的第一個元素交換。
8.遞歸的將第一二三部分排序。
疑問:為啥不用泛型
到此這篇關(guān)于深入理解java中Arrays.sort()的用法的文章就介紹到這了,更多相關(guān)java Arrays.sort()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
鎖超時發(fā)現(xiàn)parallelStream并行流線程上下文坑解決
這篇文章主要為大家介紹了鎖超時發(fā)現(xiàn)parallelStream并行流線程上下文坑解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
Java 實現(xiàn)word模板轉(zhuǎn)為pdf
這篇文章主要介紹了Java 實現(xiàn)word模板轉(zhuǎn)為pdf的方法,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-02-02
IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大
這篇文章主要介紹了IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
SpringBoot應(yīng)用的打包和發(fā)布實現(xiàn)
本文主要介紹了SpringBoot應(yīng)用的打包和發(fā)布實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
java jni調(diào)用c函數(shù)實例分享(java調(diào)用c函數(shù))
Java代碼中調(diào)用C/C++代碼,當(dāng)然是使用JNI,JNI是Java native interface的簡寫,可以譯作Java原生接口,下面看實例吧2013-12-12
Springboot動態(tài)切換數(shù)據(jù)源的具體實現(xiàn)與原理分析
目前有個需求,需要使用不同的數(shù)據(jù)源,例如某業(yè)務(wù)要用A數(shù)據(jù)源,另一個業(yè)務(wù)要用B數(shù)據(jù)源,所以下面這篇文章主要給大家介紹了關(guān)于Springboot動態(tài)切換數(shù)據(jù)源的具體實現(xiàn)與原理分析,需要的朋友可以參考下2021-12-12
SpringBoot項目實現(xiàn)日志打印SQL的常用方法(包括SQL語句和參數(shù))
有時候遇到問題需要根據(jù)我們編寫的SQL進行分析,但如果不進行一些開發(fā)或者配置的話,這些SQL是不會打印到控制臺的,它們默認(rèn)是隱藏的。下面給大家介紹幾種常用的方法,感興趣的朋友跟隨小編一起看看吧2024-04-04
SpringBoot+BootStrap多文件上傳到本地實例
這篇文章主要介紹了SpringBoot+BootStrap多文件上傳到本地實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

