자바의 정렬도 다른 언어들과 마찬가지로 기본적으로는 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(비교대상)
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