자바 Arrays.sort 와 Collections.sort 정렬 실현 원리 분석
6382 단어 JavaArrays.sortCollections.sort
정렬
2.원리
사실 Collections.sort 방법의 밑바닥 은 호출 된 array.sort 방법 이 며,Collections.sort 또는 Arrays.sort 방법 이 든,
소스 코드 를 추적 해 보 세 요.우선 데모 를 쓰 겠 습 니 다.
public static void main(String[] args) {
List<String> strings = Arrays.asList("6", "1", "3", "1","2");
Collections.sort(strings);//sort
for (String string : strings) {
System.out.println(string);
}
}
더 이상 간단 할 수 없 을 정도 로 간단 한 방법 입 니 다.한 걸음 한 걸음 추적 합 시다.OK,아래 를 보 니 collections.sort 방법 으로 호출 된 list.sort 가 발견 되 었 습 니 다.
그리고 추적 해 보 세 요.list 안에 sort 방법 이 있 습 니 다.그러나 list 는 인터페이스 입 니 다.분명히 하위 클래스 의 실현 을 호출 하 는 것 입 니 다.여기 서 우리 demo 는 Arrays.asList 방법 을 사용 하기 때문에 사실은 우리 의 하위 클래스 는 arraylist 입 니 다.OK,array list 에서 sort 가 실현 되 는 것 을 보고 첫 번 째 를 선택 하 세 요.왜 두 번 째 를 선택 하지 않 습 니까?2 층 댓 글 을 볼 수 있 습 니 다.정확하게 답 했 습 니 다.쉽게 말 하면 Arrays.sort 로 만 든 ArrayList 대상 입 니 다)
OK,안에 호출 된 Arrays.sort(a,c)발견;a 는 list 이 고 c 는 비교 기 입 니 다.이 방법 을 살 펴 보 겠 습 니 다.
우 리 는 비교 기 를 쓰 지 않 았 기 때문에 두 번 째 항목 을 사용 합 니 다.Legacy Merge Sort.userrequired 이 bool 값 은 무엇 입 니까?
이 값 을 추적 하면 다음 과 같은 정의 가 있 습 니 다.
> Old merge sort implementation can be selected (for
> compatibility with broken comparators) using a system property.
> Cannot be a static boolean in the enclosing class due to
> circular dependencies. To be removed in a future release.
어차피 오래된 병합 정렬 이 니 상관 하지 마 세 요.지금 은 기본적으로 꺼 져 있 습 니 다.
OK,우리 가 가 는 것 은 sort(a)라 는 방법 입 니 다.이어서 이것 에 들 어 갑 니 다.
이어서 저희 의 중요 한 sort 방법 을 보도 록 하 겠 습 니 다.
static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen) {
assert a != null && lo >= 0 && lo <= hi && hi <= a.length;
int nRemaining = hi - lo;
if (nRemaining < 2)
return; // array 0 1
// MIN_MERGE(32) , "mini-TimSort" ,jdk1.7
if (nRemaining < MIN_MERGE) {
// , , ,
int initRunLen = countRunAndMakeAscending(a, lo, hi);
// 32 , binarySort
binarySort(a, lo, hi, lo + initRunLen);
return;
}
// array, , mini-TimSort, , TimSort
ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);
int minRun = minRunLength(nRemaining);
do {
// Identify next run
int runLen = countRunAndMakeAscending(a, lo, hi);
// 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);
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;
}
5 로 돌아 가면 우 리 는 우리 가 비교 기 를 썼 을 때 사용 한 것 을 볼 수 있다TimSort.sort
소스 코드 는 다음 과 같다.
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;
}
위의 sort 방법 과 같 습 니 다.사실은 Timsert 의 소스 코드 입 니 다.3.총화
Collections.sort 방법 이 든 Arrays.sort 방법 이 든 바 텀 실현 은 모두 Timsert 에서 이 루어 진 것 입 니 다.이것 은 jdk 1.7 에 추 가 된 것 이 고 예전 에는 병합 순 서 였 습 니 다.Timsert 알고리즘 은 정렬 된 데이터 의 하위 서열 을 찾 은 다음 나머지 부분 을 정렬 한 다음 합 친 것 입 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.