자바 의 정렬 요약

프로젝트 개발 에서 우 리 는 항상 한 그룹의 데 이 터 를 정렬 하거나 오름차 순 또는 내림차 순 으로 해 야 한다. 자바 에서 정렬 하 는 방법 은 여러 가지 가 있다. 가장 촌 스 러 운 방법 은 바로 스스로 정렬 알고리즘 을 쓰 는 것 이다. 예 를 들 어 거품 정렬, 빠 른 정렬, 이 진 트 리 정렬 등 이다. 그러나 보통 스스로 쓸 필요 가 없다. JDK 는 우리 에 게 많은 정렬 알고리즘 을 제공 해 주 었 기 때문에 우 리 는 직접 가 져 와 서 사용 하면 된다.
        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 인 터 페 이 스 는 클래스 의 확장 정렬 도구 입 니 다.

좋은 웹페이지 즐겨찾기