[Java] Comparable, Comparator 인터페이스를 사용하여 비교하고자 하는 기준을 정해 객체를 내맘대로 정렬하기
Comparable 인터페이스, Comparator 인터페이스를 사용함으로써 비교하고자 하는 기준을 정해 객체를 내 마음대로 정렬할 수 있다.
말이 조금 어려울 수 있다.
Comparable, Comparator 인터페이스는 객체를 정렬시킬 때 꼭 등장하는 놈들이다.
Comparable은 '비교할 만한', '견줄만한'하다는 의미를 가지고 Comparator는 '비교 측정기' 라는 의미를 가진 것처럼 이놈들의 용도는 객체를 정렬하기 위한 기준을 정하는 것이다.
Comparable 인터페이스에는 compareTo(T o) 메서드가 정의되어 있어 이를 구현해야 하고
Comparator 인터페이스에는 compare(T o1, T o2) 메서드가 정의되어 있어 이를 구현해야 한다.
위 두 개의 메서드를 통해 추측해볼 수 있는 것은 Comparable 인터페이스는 '자기 자신과 매개변수 객체를 비교' 하는 것이고 Comparator는 '두 매개변수의 객체를 비교'하는 것이다.
아래와 같은 Student 클래스가 존재한다고 가정하자.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
private int age;
}
Student 객체를 담는 리스트를 만들어보자.
List<Student> students = Arrays.asList(
new Student(1, "james", 40),
new Student(4, "kevin", 30),
new Student(3, "zila", 35),
new Student(2, "hello", 28),
new Student(5, "boy", 39)
);
students를 출력해보자
System.out.println(students);
// [Student(id=1, name=james, age=40), Student(id=4, name=kevin, age=30), Student(id=3, name=zila, age=35), Student(id=2, name=hello, age=28), Student(id=5, name=boy, age=39)]
리스트가 출력될 때 리스트에 넣은 순서대로 출력이 된다.
Comparable 인터페이스와 compareTo(T o) 메서드
그런데 만약 나이 순으로 정렬을 하고 싶다면 어떻게 해야할까.
Comparable 인터페이스가 정의해놓은 compareTo(T o) 메서드를 오버라이딩하여 이를 구현해주면 된다.
compareTo(T o) 메서드를 오버라이딩 하기 위해서는 Students 클래스는 Comparable 인터페이스를 구현해야 한다.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Comparable<Student> {
private int id;
private String name;
private int age;
@Override
public int compareTo(Student s) {
return this.getAge() - s.getAge();
}
}
compareTo() 메서드를 오버라이딩하여 return 부분을 나이 순으로 정렬하게끔 구현해줘야 한다.
아래는 각각 오름차순, 내림차순 정렬을 구현했다.
// 오름차순
@Override
public int compareTo(Student student) {
return this.getAge() - student.getAge();
}
// 내림차순
@Override
public int compareTo(Student student) {
return student.getAge() - this.getAge();
}
오름차순으로 정렬했다고 가정하고 리스트 출력을 다시 해보자.
Collections.sort(students); // 오름차순으로 정렬
System.out.println(students);
//[Student(id=2, name=hello, age=28), Student(id=4, name=kevin, age=30), Student(id=3, name=zila, age=35), Student(id=5, name=boy, age=39), Student(id=1, name=james, age=40)]
Comparator 인터페이스와 compare(T o1, T o2) 메서드
compareTo(T o) 메서드를 오버라이딩하여 나이 순으로 객체를 정렬했다면 compare(T o1, T o2) 메서드를 오버라이딩하여 나이 순으로 또한 객체를 정렬할 수도 있다.
그럼 Student 클래스가 Comparator 인터페이스를 구현하고 compare(T o1, T o2) 메서드만 오버라이딩해서 될까?
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Comparator<Student> {
private int id;
private String name;
private int age;
@Override
public int compare(Student s1, Student s2) {
return s1.getAge() - s2.getAge();
}
}
컴파일 에러가 날 것이다.
왜냐하면 리스트를 정렬하기 위해서는 Collections.sort() 를 사용하기 때문이다.
Collections.sort() 메서드에 매개변수로 넣을 수 있는 리스트의 자료형은 Comparable을 구현하는 자료형이어야 하기 때문이다.
위에 Comparable 부분에서는 Student 객체가 Comparable<Student>를 구현했기 때문에 Collections.sort() 메서드를 사용할 수 있었던 것이다.
정렬하는 방법은 추후 작성 ㅇㅖ 정