본문 바로가기

Java & JSP

[Java] Comparable, Comparator의 차이

728x90
반응형

 

 

알고리즘을 조금씩 풀어보고 있는데 자바의 기본기가 많이 부족하다는 것을 깨달았다.

객체를 정렬할 때 사용할 두 가지 방식을 알아보려고 한다.

먼 방식이 비슷한게 두개나 있는겨.. 헷갈려..🤯

 

 


 

 

Comparable

public void main(String[] args) {
	
    Career[] arr = new Career[2];
    arr[0] = new Career(10,5);
    arr[1] = new Career(3,7);
    
    Arrays.sort(arr); // age 기준 오름차순 정렬 (index) 1, 0
    
}

class Career implements Comparable<Career> {
 
	int age;	// 나이
	int year;	// 연차
	
	Career(int age, int year) {
		this.age = age;
		this.year = year;
	}
	
	@Override
	public int compareTo(Career o) {
    
        /* 1 */
		// 자기자신의 age가 o의 age보다 크다면 양수
		if(this.age > o.age) {
			return 1;
		}
		// 자기 자신의 age와 o의 age가 같다면 0
		else if(this.age == o.age) {
			return 0;
		}
		// 자기 자신의 age가 o의 age보다 작다면 음수
		else {
			return -1;
		}
        
        /* 2 */
        // return this.age - o.age;
	}
}

 

- Comparable은 인터페이스이다. compareTo 메서드를 오버라이딩 하여 정렬을 구현한다.

- 해당 코드로 정렬하면 오름차순 정렬이 된다.

- 객체의 프로퍼티를 사용해(여기서는 age) 정렬 기준을 조건으로 주고, 정수를 반환하도록 한다.

- 비교 대상은 자신 객체와 compareTo의 매개변수로 오는 객체와 비교한다.

- 1번 방식으로 정석대로 사용할 수도 있고, 결과가 정수 반환만 되면 되는거니 축약 해서 2번처럼 사용할 수 있다.

 

- 리턴 값이 음수이면 그대로, 양수이면 값을 교체한다.

난 이게 항상 의문이었는데, 아래 내용을 보면 조금 이해가 될 것이다.

자바에서는 오름차순이 디폴트이다. 이 말은 선행 원소가 후행 원소보다 작다는 뜻이다.

즉 비교 시 음수가 나오면 두 원소의 위치는 바뀌지 않는다.

예를 들어, 선행:3, 후행:1 요소를 비교한다면

3-1 = 2 즉 선행 원소가 후행 원소보다 크고 양수가 나와서 두 원소의 위치를 바꿀 것이다.

그럼 1,3 로 오름차순 정렬이 될 것이다.

 

이 규칙을 일반화하면

 

음수일 경우 : 두 원소 위치 교환 안함

양수일 경우 : 두 원소 위치 교환 함

 

이렇게 이해하고 정렬 코드를 짜면 의문이 어느 정도 해결되지 않을까 싶다.

 

 

Comparator

public void main(String[] args) {
	
    Career[] arr = new Career[2];
    arr[0] = new Career(10,5);
    arr[1] = new Career(3,7);
    
    Comparator<Career> comp = new Comparator<Career>() {
        @Override
        public int compare(Career o1, Career o2) {
            return o1.year - o2.year;
        }
    };
    
    Arrays.sort(arr, comp); // year 기준 오름차순 정렬 (index) 1, 0
    
}

class Career implements Comparator<Career> {
 
	int age;	// 나이
	int year;	// 연차
	
	Career(int age, int year) {
		this.age = age;
		this.year = year;
	}
}

 

- Comparator도 인터페이스이다. compare 메서드를 오버라이딩 하여 정렬을 구현한다. (다른 점)

- 해당 코드로 정렬하면 오름차순 정렬이 된다.

- 객체의 프로퍼티를 사용해(여기서는 year) 정렬 기준을 조건으로 주고, 정수를 반환하도록 한다.

- 비교 대상은 compare의 매개변수로 오는 두 객체를 비교한다. (다른 점)

- 정렬용 익명 객체를 여러 개 생성해서 구현할 수 있다. (다른 점)

- 1번 방식으로 정석대로 사용할 수도 있고, 결과가 정수 반환만 되면 되는거니 축약 해서 2번처럼 사용할 수 있다.

- 리턴 값이 음수이면 그대로, 양수이면 값을 교체한다.

 

두 비교 메서드의 다른 점을 참고해서 구분하여 사용하면 된다.

 

 

 

728x90
반응형