객체 간의 sort를 수행하던 중 Comparable이라고 하는 것과 Comparator라고 하는 것이 존재해 둘 중 어떤 걸 어느 상황에 써야 하나..라는 생각으로 작성했다.
공통점
- 모두 인터페이스다.
- 원하는 객체에 추가하고, 각각 요구로 하는 메서드(비교 메서드)를 구현해주면 된다.
Comparable
- compareTo(T o) return: int
- 자기 자신과 매개변수 객체를 비교한다.
- 자기 자신을 기준으로 내가 더 크면 양수, 상대가 더 크면 음수를 반환하여 사용한다.
- 문자열의 경우 좀 다른데, 기준값에 비교대상이 포함되어 있다면, 서로의 문자열 길이의 차이값을 리턴한다.
- 뭔소리냐하면 예시를 보자
String str = "abcd";
System.out.println(str.compareTo("abcd")); // 같기 때문에 0이 나온다.
System.out.println(str.compareTo("ab")); // abcd안에 ab가 포함되어 있기 때문에 두 문자열의 차이인 2
System.out.println(str.compareTo("a")); // 같은 이유로 1
System.out.println(str.compareTo("c")); //이 친구는 -2가 나온다.
// 같은 위치의 문자만 비교하기 때문에, 첫번째 문자를 비교해 다르면 아스키값을 기준으로 비교한다.
Comparator
- compare(T o1, T o2)
- 두 매개변수 객체를 비교한다
- compare를 오버라이딩할 객체가 별도로 존재해야 한다.
하지만 Comparator를 정말 비교용으로만 사용하기 위해 굳이 객체를 선언하기엔 아까운 사람들을 위해
익명 객체를 생성하여 사용하는 방법이 생겼다.
익명 객체
- 말 그대로 이름이 정의되지 않은 객체다.
- 주로 특정 구현 부분만 사용하거나, 중간에 수정된 코드를 잠깐 이용할 때 사용된다.
public static void main(String[] args) {
Person a = new Person();
// 익명 객체 선언!!
Person b = new Person() {
int age;
@Override
int get() {
return age;
}
};
System.out.println(a.get());
System.out.println(b.get());
}
//////
class Person{
String name;
int height;
int get(){
return height;
}
}
해당 코드를 살펴보면 b에는 Person의 객체를 이어받아 get()을 오버라이딩 했지만, 해당 객체의 이름은 따로 지정되어있지 않은데, 이러한 객체가 익명 객체다.
여기서 살펴볼 점은 저 b에 저장된 익명객체는 기존의 Person이 가지고 있던 name과 height 외에 age라는 변수가 추가되었다. 어디서 많이 본 방식인데.. 하고 생각해 보면 상속된 클래스와 같은 형태라고 볼 수 있다.
생성되는 익명 객체는 기존 클래스의 상속 관계이라는 말이 된다.
익명 객체로 Comparator 구현하기
익명 객체가 뭐 하는 객체인지도 알았고, Comparator가 어떤 방식으로 돌아가는지도 알아보았다. 이제 이 둘을 잘 엮어서 Comparator라는 인터페이스를 구현할 익명 객체를 만들어 두 객체를 비교해 주는 compare 메서드를 구현하게 되면 compare를 자유롭게 사용할 수 있게 되는 것이다.
public static void main(String[] args) {
Person a = new Person("호날두", 186);
Person b = new Person("메시", 170);
Comparator<Person> comp = new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2){
return p1.height - p2.height;
}
};
System.out.println(comp.compare(a, b));
}
//////
class Person{
String name;
int height;
Person(String name, int height){
this.name = name;
this.height = height;
}
}
이런 방식의 장점은 따로 객체를 만드는 것이기 때문에 여러 변수에 대해 비교 메서드를 구현할 수 있다는 점이 있다.
자매품으로 정렬을 이용할 때, Arrays.sort(arr, comp)와 같이 익명 객체를 파라미터로 사용하여 정렬을 수행하는 방법도 있다.