🎥Back/자바의 정석

[JAVA의 정석]Comparator와 Comparable

i_zzy 2024. 1. 17. 15:14

이 글은 유튜브 '자바의 정석 - 기초편'을 보고 정리한 글입니다. 

 

 

📂content

1. Comparator와 Comparable

- 객체 정렬에 필요한 메서드(정렬기준 제공)를 정의한 인터페이스 

Comparable 기본 정렬기준을 구현하는데 사용

Comaprator 기본 정렬기준 외에 다른 기준으로 정렬하고자할 때 사용 

o1 > o2 : 양수
o1 == o2 : 같다
o1 < o2 : 음수 
- compareTo는 o와 this를 비교함. 
- 정렬(sort)은 두 대상을 비교해서 자리바꿈하는 것을 반복하는 것이다. 

 

 

- compare()와 compareTo()는 두 객체의 비교결과를 반환하도록 작성 

  같으면 0, 오른쪽이 크면 음수(-), 작으면 양수(+)

오름차순은 1,2,3,4....순이다. 따라서 7,5일 때 자리를 바꾼다(왼쪽 값이 클 때). 7 > 5 
내림차순은 4,3,2,1...순이다. 따라서 5,7일 때 자리를 바꾼다(오른쪽 값이 클 때). 5 < 7

 

 

 

⍟실습

더보기
package etc;

import java.util.Arrays;
import java.util.Comparator;

public class Ex11_7 {
    public static void main(String[] args) {
        String[] strArr = {"cat", "Dog", "lion", "tiger"};

        Arrays.sort(strArr); // String의 Comparable구현에 의한 정렬
        System.out.println("strArr=" + Arrays.toString(strArr));

        //Arrays.sort(정렬대상, 정렬기준)
        //CASE_INSENSITIVE_ORDER : String 클래스에 있는 static 상수
        Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 구분안함
        System.out.println("strArr=" + Arrays.toString(strArr));

        Arrays.sort(strArr, new Descending()); // 역순 정렬
        System.out.println("strArr=" + Arrays.toString(strArr));
    }
}

class Descending implements Comparator {
    public int compare(Object o1, Object o2){
        if( o1 instanceof Comparable && o2 instanceof Comparable) {
            Comparable c1 = (Comparable)o1;
            Comparable c2 = (Comparable)o2;
            return c1.compareTo(c2) * -1 ; // -1을 곱해서 기본 정렬방식의 역으로 변경한다.
            // 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 된다.
        }
        return -1;
    }
}

 

 - 자주 써서 String클래스에 Comparator을 만들어놓음 

- 정렬을 할 때는 정렬대상정렬기준이 있어야 한다. 

   `static void sort(Object[] a)` //객체 배열에 저장된 객체가 구현한 Comparable에 의한 정렬

   `static void sort(Object[] a, Comparator c)` //지정한 Comparator에 의한 정렬

- 문자열의 기본정렬순서는 사전순 

 

 

 

 

 

2. Integer와 Comparable

- 5-5 = 0 두 수가 같다
  5-7 = -2 오른쪽이 크다
  7-5 = 2 왼쪽이 크다  

그렇다면 왜 더 간단한 코드인 - 가 아닌 삼항연산자를 사용하는 것일까? 
삼항연산자가 성능이 2~3%가 더 빠르다.  Integer은 32bit인데 뺄셈을 하면 전부 다 끝까지 계산해야함. 그런데 삼항연산자가 비교를 하니까 앞부분에서 결정날 확률이 높기때문이다. (예) 10101010 - 01010)

 

 

두 수의 차이로 어떻게 정렬을 만들지? 

 

 

⚝ 버블 정렬

public static void main(String[] args) {
        int[] intArr = new int[10];
        for(int i=0; i< intArr.length - 1 ; i++){
            for(int j = 0; j < intArr.length -1; j++){
                int tmp = 0; 
                
                if(intArr[j] > intArr[j+1]){//정렬기준
                	//자리 바꿈
                    tmp = intArr[j];
                    intArr[j] = intArr[j+1];
                    intArr[j+1] = tmp;
                }
            }//for
        }
    }
정렬의 큰 로직은 변하지 않는다. 다만 비교를 어떻게 할 것인가만 바뀐다. 즉, 정렬 기준만 달라진다. 

 

 

 

 

 

출처