Custom Sort

전우재·2024년 3월 1일

Study

목록 보기
4/4

목적

  • java에서 문제를 해결할 때 일반적인 배열이 아닌 클래스를 정렬시킬 때, 오름차순이나 내림차순 방법이 헷갈리는 경우가 종종 있어 확실하게 하고자 글을 작성하게 되었다.
  • 해당 글에서 정렬 방법을 수정하는 코드를 연습하고, ComparableComparator를 사용하는 방법을 비교한다.

Comparable 인터페이스

  • Comparable 인터페이스는 객체의 순서를 정의하는데 사용된다.
  • 이를 사용하기 위해 해당 인터페이스를 구현하는 클래스에서 compareTo 메소드를 override해야한다.

예시 코드

public class Student implements Comparable<Student> {
    private String name;
    private int age;

    // 생성자, getter, setter 생략...

    @Override
    public int compareTo(Student otherStudent) {
        return this.name.compareTo(otherStudent.getName());
    }
}
  • 이렇게 Comparable인터페이스를 구현한 Student클래스의 인스턴스들은 Arrays.sort()Collecitons.sort()메서드를 호출하면 이름순으로 정렬된다.

Comparator 인터페이스

  • Comparator 인터페이스 또한 객체의 순서를 변경하거나, 특정 속성에 따라 정렬하고 싶을 때 사용된다.
  • 보통 익명 클래스로 사용된다.

예시 코드

Comparator<Student> comparator = new Comparator<>() {
    @Override
    public int compare(Student s1, Student s2) {
        return s1.getName().compareTo(s2.getName());
    }
};

List<Student> students = new ArrayList<>();
// 학생들 추가...
Collections.sort(students, comparator);

// java 8이후 람다식
List<Student> students = new ArrayList<>();
// 학생들 추가...
students.sort((s1, s2) -> s1.getName().compareTo(s2.getName()));

차이점

  • 두 방법은 객체를 정렬하는데 사용되는 공통점이 있지만, 구현의 차이점 외에 사용시기에도 차이가 있다.
  • Comparable은 객체의 순서를 미리 정의하여 사용하는데 반해, Comparator는 특정 속성에 따라 객체를 정렬할 수 있다.

헷갈리는 compareTo

  • compareTo()를 구현할 때 어떤 순서로 정렬되는지 헷갈릴 때가 종종 있다.
  • 보통 예시 코드에서 비교할 값들의 차를 바로 반환하게 되면서 잘 이해하지 못한게 그 이유라고 생각되어 좀 더 알기 쉽도록 구현하려고 한다.

Comparable을 구현한 클래스에서 사용하는 경우

@Override
public int compareTo(Student other) {
    if (this.age > other.age) {
        return 1;
    } else if (this.age == other.age) {
        return 0;
    } else if (this.age < other.age) {
        return -1;
    }
}
  • 해당 방법을 사용하면 만약 값끼리 연산을 반환했을 때 발생하는 underflowoverflow도 방지할 수 있다.

Comparator를 구현하여 사용하는 경우

  • Comparator를 구현하여 사용하는 경우는 앞과 비슷하게 사용할 수 있지만 람다식을 사용하면 여로 조건으로 정렬하는 경우에도 더 쉽게 표현할 수도 있다.
// 이름 순으로 정렬, 이름이 같다면 나이가 많은 순서부터 정렬
Comparator<Person> comparator = Comparator
    .comparing(Person::getName)
    .thenComparing(Person::getAge, Comparator.reverseOrder());
  • comparing(비교대상)을 사용하여 정렬할 수 있고, 만약 같을 때 추가 조건이 있으면 thenComparing(비교대상)을 사용해 정렬할 수 있다.
  • 기본적으로 오름차순 정렬이지만, sort()처럼 인수에 Comparator.reverseOrder()를 추가하면 내림차순으로 정렬할 수 있다.

참고 문서

Java 공식 문서 - Arrays, Collections, Comparable, Comparator

0개의 댓글