본문 바로가기

미역/자바

Comparable 과 Comparator

  • Comparable 인터페이스를 사용하기 위해선 compareTo 메소드를 구현해야 한다.
  • Comparator 인터페이스를 사용하기 위해선 compare 메소드를 구현해야 한다.

 ➜ 그러면 compareTo 와 compare 의 차이점은 무엇인가?

 

  • compareTo(Type o)
  • compare(Type o1, Type o2)

 ➜ 매개변수가 다르다. 코드를 통해 보는 게 더 쉽다.

 

 1. Comparable

 compareTo는 객체 자신과 매개변수를 비교하는 메소드이다.

class Stick implements Comparable<Stick>{
	int len;
	
	Stick(int len){
		this.len = len;
	}
	
	public int compareTo(Stick o) {
		if(this.len - o.len < 0) {
			return -1;
		}else if(this.len - o.len > 0) {
			return 1;
		}else {
			return 0;
		}
	}
}

 

 2. Comparator

compare는 매개변수 둘을 비교하는 메소드이다.

class Stick implements Comparator<Stick>{
	int len;
	
	Stick(int len){
		this.len = len;
	}
	
	public int compare(Stick o1, Stick o2) {
		if(o1.len - o2.len < 0) {
			return -1;
		}else if(o1.len - o2.len > 0) {
			return 1;
		}else {
			return 0;
		}
	}
}

 

우선 정렬을 다루기 전 알아둬야 할 사실이 있다. Java는 기본적으로 오름차순 정렬을 기준으로 한다. 때문에 위의 compareTo와 compare의 코드에서 볼 수 있듯이 '전자' - '후자'가 음수라면 '후자'가 더 크다는 의미이니 자리를 바꾸지 않고(return -1) '전자' - '후자'가 양수라면 '전자'가 더 크다는 의미이니 오름차순 정렬을 위해 자리를 바꾼다(return 1).

 

 - Comparable 과 Comparator의 활용

 단순 대소 비교 로직을 위해서 Comparable 과 Comparator를 사용하지는 않을 거다. 아마 모두가 객체를 원하는 대로 정렬하기 위해서 Comparable 과 Comparator를 사용하려는 것일 거다. compareTo와 compare는 위에서 말한 차이점으로 인해 활용에 차이가 있다. 그러니 내가 원하는 객체의 정렬을 위해 어느 메소드가 더 좋을지 생각하고 사용하면 된다.

 

 1. Comparable

class Stick implements Comparable<Stick>{
	int len;
	
	Stick(int len){
		this.len = len;
	}
	
	public int compareTo(Stick o) {
		if(this.len - o.len < 0) {
			return -1;
		}else if(this.len - o.len > 0) {
			return 1;
		}else {
			return 0;
		}
	}
	
}
public static void main(String[] args) throws Exception {
		
	List<Stick> arr = new ArrayList<Stick>();
	arr.add(new Stick(5));
	arr.add(new Stick(8));
	arr.add(new Stick(3));
	
	System.out.println("<정렬 전>");
	System.out.println("arr : "+arr);
	Collections.sort(arr);
	System.out.println("<정렬 후>");
	System.out.println("arr : "+arr);
	
}
<정렬 전>
arr : [5, 8, 3]
<정렬 후>
arr : [3, 5, 8]

 Collections.sort()를 사용해 리스트를 정렬했다. 

 Collections.sort()에서 리스트 안의 객체 안의 오버라이드 된 compareTo를 사용해서 정렬을 해준다.   

 현재 객체의 값이 더 작을 때, -1을 리턴해서 자리를 바꾸지 않았으므로 오름차순 정렬이 된다.

 

2. Comparator

 compare은 익명객체를 생성할 때 유용하다.

class Stick{
	int len;
	
	Stick(int len){
		this.len = len;
	}
	
	@Override
	public String toString() {
		return String.valueOf(this.len);
	}
}
public static void main(String[] args) throws Exception {
		
		List<Stick> arr = new ArrayList<Stick>();
		arr.add(new Stick(5));
		arr.add(new Stick(8));
		arr.add(new Stick(3));
		
		System.out.println("<정렬 전>");
		System.out.println("arr : "+arr);
		Collections.sort(arr, new Comparator<Stick>(){
			
			public int compare(Stick o1, Stick o2) {
				if(o1.len - o2.len < 0) {
					return 1;
				}else if(o1.len - o2.len > 0) {
					return -1;
				} else {
					return 0;
				}
			}
		});
		System.out.println("<정렬 후>");
		System.out.println("arr : "+arr);
	
	}
<정렬 전>
arr : [5, 8, 3]
<정렬 후>
arr : [8, 5, 3]

 

 Comparable은 자기 자신과 매개변수의 비교이기 때문에, 익명객체를 생성할 수 없다. 하지만 Comparator는 매개변수 둘의 비교이기 때문에 익명객체를 생성하기에 유용하다.

 Collections.sort()에서 두 번째 매개변수로 Comparator를 상속한 익명객체를 생성해 넣어줘서 리스트를 정렬할 수도 있다.

'전자'의 값이 더 작을 때, 1을 리턴해서 자리를 바꿨으므로 내림차순 정렬이 된다.

 

 

'미역 > 자바' 카테고리의 다른 글

그룹 합의 차이가 최소인 두 그룹으로 나누기  (0) 2021.11.15
소수 구하기  (0) 2021.11.05
그래프에서 DFS로 사이클 찾기  (0) 2021.10.28
TreeSet과 Comparator  (0) 2021.10.25
XOR의 성질  (0) 2021.10.22