자바의 정렬 Comparable과 Comparator

June Lee·2021년 2월 3일
0

Java

목록 보기
12/23

자바의 정렬도 다른 언어들과 마찬가지로 기본적으로는 Arrays.sort() (배열의 경우)를 사용한다. 이때 sort 메서드는 내부적으로 Comparable을 이용해 구현된 것이다.

< Comparable과 Comparator 차이점 >
Comparable: 오름차순으로 정렬할 때 사용 => compareTo() 오버라이딩
Comparator: 오름차순으로 정렬하지만 특별한 조작이 필요할 때, 혹은 다른 정렬 기준으로 변경하고자할 때 사용 => compare 오버라이딩

이차원 배열 혹은 객체 배열 등을 sort할 때에는 sort() 메서드를 이용해서 정렬할 수 없다. 정렬의 기준이 정해지지 않았기 때문이다.

이럴 때 Comparable 인터페이스를 implements한 후, 해당 인터페이스의 compareTo 메서드를 오버라이딩하는 방식으로 구현할 수 있다.

public class Person implements Comparable<Person> {
	@Override
	public int compareTo(Person p) {
		// 나이 기준 오름차순
		if(this.age < p.getAge()) {
			return -1; // 자리 안바꿈
		} else if (this.age > p.age) {
			return 1; // 자리 바꿈 
		}
		return 0;
	}

위와 같이 객체의 정렬에서도 숫자, 문자열 간의 일반적인 비교의 경우 비교 대상만 명시해주면(위의 경우에는 Person 클래스의 멤버 변수 중 '나이') Comparable은 사용 가능하다.

@Override
public int compareTo(Employee o) {
	return this.name.compareTo(o.name);
}

참고로, 문자열의 경우 위와 같이 String 클래스의 compareTo 메서드를 이용해 비교한다.

// compareTo 사용법

“aa”.compareTo(“bb”) -> -1 리턴

“bb”.compareTo(“aa”) -> 1 리턴

그리고 다음으로 사용할 수 있는 방법은 Comparator 인터페이스를 사용하는 것이다. Comparator 클래스를 생성하여 해당 클래스의 compare 메서드를 오버라이딩하여 원하는 정렬 기준대로 수정하여 구현한다.

public class Descending implements Comparator<Integer> {

	@Override
	public int compare(Integer o1, Integer o2) {
		// 내림차순에 대한 정렬기준을 정의 
		if(o1 < o2) {
			return 1;
		} else if (o1 > o2) {
			return -1;
		}
		return 0;
	}

}

기본 방식은 Comparator를 구현한 클래스를 만들고, compare를 오버라이딩한 후

TreeSet<Integer> set = new TreeSet<Integer>(new Descending()); 

위와 같이 Comparator 객체가 들어가면 되는 곳에 넣어서 정렬해주는 것이다.

그러나 일회성으로 사용할 정렬 기준을 위해 매번 클래스를 새로 만드는 것은 비효율적이기 때문에, 주로 다음과 같이 익명 클래스로 사용된다.

Arrays.sort(scores, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
    	if (o1[1] < o2[1]) {	//정렬기준이 array의 인덱스 1번
        	return -1;
        } else if (o1[1] > o2[1]) {
          	return 1;
        } else {
        	return 0;
        }
    }
});

여기서 new Comparator는 인터페이스를 인스턴스화한 것이 아니라, 인터페이스를 익명 클래스로 구현한 것이다.

Collections.sort(list, new Comparator<Person>() {

	@Override
	public int compare(Person o1, Person o2) {
		// 이름을 기준으로 오름차순 
		if(o1.getName().compareTo(o2.getName()) > 0) {
					return 1;
		} else if(o1.getName().compareTo(o2.getName()) < 0) {
					return -1;
		}
		return 0;
	}
});


cf) compareTo 메서드
Integer.compareTo, Double.compareTo와 같이 사용된다.
(Comparable 인터페이스의 compareTo 메서드와는 다른 메서드이다!)

사용 형태
기준값.compareTo(비교대상)

  • 비교 대상이 동일한 값의 경우 0
  • 비교 대상이 작은 경우 -1
  • 비교 대상이 큰 경우 1
    을 반환한다.
Integer x = 3;
Integer y = 4;

System.out.println(x.compareTo(y)); // -1
System.out.println(x.compareTo(3)); // 0
System.out.println(x.compareTo(1)); // 1
profile
📝 dev wiki

0개의 댓글