자바 의 정렬 요약
1. 기본 형식 배열 정렬
기본 유형의 배열 을 정렬 할 때 보통 우 리 는 Arrays 류 가 제공 하 는 sort () 방법 으로 정렬 하면 됩 니 다. 소스 코드 를 보면 sort () 방법 은 알고리즘 에 있어 서 이미 최적화 되 었 습 니 다. 특별한 수요 가 없 으 면 이 방법 은 우리 의 수 요 를 충분히 만족 시 킬 수 있 습 니 다.사례 코드 는 다음 과 같다.
public static void main(String[] args) {
//
int[] a = { 3, 5, 2, 1, 8, 6, 9, 4, 0};
//
Arrays.sort(a);
//
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
2. 대상 배열 정렬대상 배열 에 대해 정렬 을 하고 자바 에 서 는 두 가지 실현 방식 이 있 습 니 다. 하 나 는 정렬 된 대상 이 Comparable 인 터 페 이 스 를 실현 한 다음 에 Arrays 류 의 sort (Object [] a) 방법 으로 정렬 합 니 다.다른 하 나 는 하나의 실현 을 만 드 는 것 이다. Comparator 인터페이스의 단독 클래스, 그리고 Arrays 클래스 를 호출 합 니 다. sort (T [] a, Comparator c) 방법.다음은 두 가지 방법의 구체 적 인 실현 코드 를 보 겠 습 니 다.
Comparable 인 터 페 이 스 를 실현 한 Person 클래스:
public class Person implements Comparable<Person> {
private int id;
private String name;
private int age;
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
/* id、name、position getter/setter */
@Override
public int compareTo(Person o) {
// TODO
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
왜 이 인 터 페 이 스 를 실현 하면 Person 류 의 정렬 을 실현 할 수 있 습 니까?뒤에서 소개 하고 있어 요.현재 Person 클래스 를 id 에 따라 어 릴 때 부터 정렬 시 키 려 면 compare To 는 다음 과 같은 코드 를 실현 합 니 다. @Override
public int compareTo(Person o) {
return id - o.id;
}
Person 클래스 를 id 크기 에 따라 역방향 으로 정렬 하려 면 compare To 를 변경 하면 됩 니 다. return o.id - id; 됐다.하면, 만약, 만약... Person 클래스 는 id 에 따라 작은 것 부터 큰 것 까지 정렬 한 다음 에 age 에 따라 작은 것 부터 큰 것 까지 정렬 합 니 다 (여기 id 가 중복 된다 고 가정 합 니 다). compare To 는 코드 를 다음 과 같이 실현 합 니 다.
@Override
public int compareTo(Person o) {
return id - o.id != 0 ? (id - o.id) : (age - o.age);
}
compare To 실현 은 모두 자신 이 수 동 으로 작성 한 것 을 볼 수 있 습 니 다. 나중에 정렬 하 는 요소 가 많아 지면 스스로 실현 하 는 것 이 번 거 로 울 것 입 니 다.여기 서 우 리 는 Apache 의 도구 클래스 를 사용 하여 간단하게 처리 할 수 있 습 니 다. 먼저 다운로드 가 필요 합 니 다. commons - lang - *. jar 다음 에 이 가방 을 프로젝트 에 추가 하고 (Build Path 설정 을 통 해) compare To () 방법 으로 관련 종 류 를 호출 하면 됩 니 다. 현재 도 Person 류 를 id 로 정렬 하고 compare To 구현 코드 는 다음 과 같 습 니 다. @Override
public int compareTo(Person p) {
return new CompareToBuilder()
.append(id, p.id).toComparison();
}
commons - lang - *. jar 다운로드 주소:http://commons.apache.org/lang/
Compare ToBuilder 류 append () 방법 은 어떻게 비 교 를 실현 합 니까?원본 코드 는 다음 과 같 습 니 다 (int 형식 에 대한 처리).
private int comparison;
public CompareToBuilder() {
super();
comparison = 0;
}
public CompareToBuilder append(int lhs, int rhs) {
if (comparison != 0) {
return this;
}
comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
return this;
}
comparison 이 0 으로 초기 화 되 었 습 니 다. comparison 이 0 과 같 지 않 을 때, 같은 곳 을 찾 았 을 때 현재 대상 의 인용 을 되 돌려 줍 니 다.comparison 이 0 이 라면 다른 곳 을 찾 지 못 했 음 을 설명 합 니 다. 현재 들 어 오 는 인 자 를 비교 하고 결 과 를 comparison 변수 에 할당 한 다음 현재 대상 에 게 참조 해 야 합 니 다.append () 방법 은 CompareToBuilder 클래스 자 체 를 되 돌려 주기 때문에 append () 방법 을 호출 한 후에 append () 방법 을 무한 호출 할 수 있 기 때문에 새로운 비교 항목 을 추가 하려 면 append () 방법 을 추가 하면 됩 니 다. 실현 방법 은 간단 하지만 치밀 합 니 다.
위의 분석 과 코드 에 대한 이 해 를 바탕 으로 Person 류 는 먼저 id 에 따라 정렬 하고 id 가 같 으 면 age 에 따라 정렬 합 니 다. 코드 는 다음 과 같 습 니 다.
@Override
public int compareTo(Person p) {
return new CompareToBuilder()
.append(id, p.id)
.append(age, p.age).toComparison();
}
역순 정렬 에 있어 서 는 더욱 간단 합 니 다. id 와 p. id 를 위 치 를 바 꾸 면 됩 니 다.
정렬 대상 을 다 썼 습 니 다. 그러면 테스트 클래스 를 시작 하 겠 습 니 다. 코드 는 다음 과 같 습 니 다.
public static void main(String[] args) {
Person[] persons = {
new Person(2, " ", 25),
new Person(1, " ", 23),
new Person(1, " ", 21),
new Person(2, " ", 24),
new Person(3, " ", 22)
};
Arrays.sort(persons);
for(Person person : persons) {
System.out.println(person.toString());
}
}
결 과 는 다음 과 같다.
Person [id=1, name= , age=21]
Person [id=1, name= , age=23]
Person [id=2, name= , age=24]
Person [id=2, name= , age=25]
Person [id=3, name= , age=22]
그 결과 Person 류 는 id 에 따라 정렬 한 다음 age 에 따라 정렬 한 것 으로 나 타 났 다.그러면 Arrays 클래스 sort (Object [] a) 방법 은 어떻게 정렬 합 니까?Arrays 클래스 부분 원본 코드 는 다음 과 같 습 니 다.
public static void sort(Object[] a) {
Object[] aux = (Object[])a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
int length = high - low;
// (INSERTIONSORT_THRESHOLD=7)
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low && ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
/* */
}
mergeSort () 방법 에서 우 리 는 이 방법 이 정렬 대상 을 호출 하 는 copare To () 방법 임 을 알 수 있 으 며, 이 방법의 다른 처리 에서 도 copare To () 방법 을 호출 하여 정렬 대상 을 비교 하 는 것 (관심 있 는 것 은 소스 코드 를 볼 수 있 습 니 다) 을 볼 수 있 습 니 다.위의 방식 으로 대상 배열 을 정렬 하지만 정렬 된 대상 이 comparable 인 터 페 이 스 를 실현 하지 않 으 면 sort () 방법 을 호출 할 때 ClassCastException 을 던 집 니 다. 이상 하 다
상기 사례 는 대상 배열 에 대한 순 서 를 실현 하지만 이런 방식 의 실현 으로 인해 특정한 대상 에 대한 배열 순 서 는 유일한 정렬 방식 만 있 을 수 있다. 프로젝트 에서 우 리 는 서로 다른 곳 에서 서로 다른 정렬 방식 을 사용 해 야 할 수도 있다. 분명히 위의 실제 방식 은 우리 의 요 구 를 만족 시 키 지 못 할 것 이다. 이때 우 리 는 하 나 를 만들어 서 실현 할 수 있다. Comparator 인터페이스의 단독 클래스 는 우리 가 실현 할 수 있 도록 도와 준다 (두 번 째 실현 방식). 클래스 를 만 드 는 코드 는 다음 과 같다.
public class PersonComprator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return new CompareToBuilder()
.append(o1.getId(), o2.getId())
.append(o1.getAge(), o2.getAge()).toComparison();
}
}
이 종 류 는 Comparator 인 터 페 이 스 를 실현 하고 범 형 을 통 해 정렬 대상 을 제한 하 였 으 며, 주의해 야 할 것 은 이곳 은 compare To () 방법 이 아니 라 compare () 방법 이 며, 실현 에 있어 서 미세한 차이 가 있다 는 것 이다.테스트 코드 를 똑 같이 봅 니 다.
public static void main(String[] args) {
Person[] persons = {
new Person(2, " ", 25),
new Person(1, " ", 23),
new Person(1, " ", 21),
new Person(2, " ", 24),
new Person(3, " ", 22)
};
Arrays.sort(persons, new PersonComprator());
for(Person person : persons) {
System.out.println(person.toString());
}
}
이전 테스트 클래스 와 의 차 이 는 Arrays 클래스 를 호출 하 는 것 입 니 다. sort (T [] a, Comparator c) 방법 은 sort (Object []) 방법 을 대체 했다.결 과 는 이전 과 마찬가지 로 열거 되 지 않 았 다.
마찬가지 로 우 리 는 소스 코드 를 통 해 이 방법 이 어떻게 정렬 을 실현 하 는 지 볼 수 있다. 소스 코드 는 다음 과 같다.
public static <T> void sort(T[] a, Comparator<? super T> c) {
T[] aux = (T[])a.clone();
if (c==null)
mergeSort(aux, a, 0, a.length, 0);
else
mergeSort(aux, a, 0, a.length, 0, c);
}
private static void mergeSort(Object[] src,
Object[] dest,
int low, int high, int off,
Comparator c) {
int length = high - low;
// (INSERTIONSORT_THRESHOLD=7)
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i
low && c.compare(dest[j-1], dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
/* */
}
방법 은 처음에 정렬 된 대상 배열 을 복제 하여 비교 기 가 비어 있 는 지 판단 하고 비어 있 으 면 첫 번 째 정렬 방식 으로 정렬 합 니 다.비어 있 지 않 은 경우 비교 기 를 포함 한 정렬 방법 을 호출 합 니 다. 이 방법 은 바로 비교 기의 copare () 방법 으로 대상 의 크기 를 비교 하여 대상 배열 의 순 서 를 실현 하 는 것 입 니 다. 여기 서 원 리 를 실현 하 는 것 도 대체적으로 알 수 있 습 니 다.
3. 대상 목록 정렬
대상 이 누적 되 고 정렬 되 지 않 는 것 은 기본적으로 대상 배열 의 정렬 과 같 으 며, 모두 Comparable 인 터 페 이 스 를 실현 하거나 새로 만 드 는 것 을 통 해 이 루어 질 수 있다. Comparator 인터페이스의 단독 클래스 로 이 루어 집 니 다.정렬 에 사용 되 는 클래스 는 Arrays 클래스 가 아니 라 Collections 입 니 다. 클래스, 이 클래스 는 java. util 패키지 에서 테스트 클래스 코드 는 다음 과 같 습 니 다.
public static void main(String[] args) {
//
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(2, " ", 25));
persons.add(new Person(1, " ", 23));
persons.add(new Person(1, " ", 21));
persons.add(new Person(2, " ", 24));
persons.add(new Person(3, " ", 22));
//
Collections.sort(persons);
//
for(Person person : persons) {
System.out.println(person.toString());
}
}
목록 의 역순 정렬 에 대해 서 는 두 가지 해결 방법 이 추가 되 어 있 습 니 다. 첫 번 째 는 Collections. reverse (List list) 방법 을 직접 사용 하여 이 루어 집 니 다. 위의 정렬 코드 를 Collections. reverse (persons) 로 바 꿉 니 다.두 번 째 는 Collections. sort (list, Collections. reverseOrder (new Position Comparator ()) 를 통 해 이 루어 지고 정렬 코드 는 Collections.sort(persons, new PersonCompator())。 요약: Comparable 인 터 페 이 스 는 클래스 의 기본 정렬 법 으로 사용 할 수 있 고 Comparator 인 터 페 이 스 는 클래스 의 확장 정렬 도구 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.