공부/이펙티브코틀린

아이템 42 - compareTo 의 규약을 지켜라

띵커베르 2024. 8. 10. 11:23
728x90
compareTo 메서드는 Any 클래스에 있는 메서드가 아닙니다.
이는 수학적인 부등식으로 변환되는 연산자 입니다.

 

 

compareTo는 객체의 자연 순서를 정의하는 메서드로, 코틀린에서는 Comparable 인터페이스를 구현할 때 반드시 준수해야 할 중요한 규약을 가진다. 이 규약을 올바르게 준수하지 않으면, 정렬이나 이진 탐색 같은 알고리즘에서 예기치 못한 결과가 발생할 수 있다.

 

compareTo 규약

  1. 반사성 (Reflexive): a.compareTo(a) == 0은 항상 true여야 한다.
  2. 대칭성 (Symmetric): a.compareTo(b) == 0이면 b.compareTo(a) == 0도 성립해야 한다.
  3. 추이성 (Transitive): a.compareTo(b) > 0이고 b.compareTo(c) > 0이면 a.compareTo(c) > 0이 되어야 한다.
  4. 일관성 (Consistency): a.compareTo(b)의 결과가 변경되지 않은 a와 b에 대해 반복적으로 호출되더라도 동일해야 한다.
  5. 비교와 동등성의 일관성: a.compareTo(b) == 0이면 a.equals(b)도 true여야 한다. 하지만 그 반대는 성립하지 않아도 된다.

 

코틀린에서는 sortedBy 를 사용하여 정렬할 수 있고 여러 프로퍼티를 기반으로 정렬해야 한다면 sortedWith 함수를 사용하면 된다.

 

 

thenByDescending은 코틀린에서 여러 조건을 기반으로 컬렉션을 정렬할 때 사용하는 함수로, 내림차순으로 정렬 조건을 추가할 때 사용됩니다.

sortedWith 함수는 Comparator를 사용하여 리스트를 정렬하는데, 이때 compareBy와 thenBy, thenByDescending을 조합하여 여러 프로퍼티를 기준으로 정렬할 수 있습니다.

  • compareBy: 첫 번째 정렬 기준을 설정합니다. 예를 들어, it.displaySequence는 displaySequence 프로퍼티를 기준으로 오름차순 정렬합니다.
  • thenBy: 이전 정렬 기준이 동일한 경우, 추가적인 정렬 기준을 오름차순으로 적용합니다.
  • thenByDescending: 이전 정렬 기준이 동일한 경우, 추가적인 정렬 기준을 내림차순으로 적용합니다.
// 최근에 추가한 코드중 일부
val sortedList = targets.cornerContentsList!!.sortedWith(
    compareBy<DisplayCornerContents> { it.displaySequence }.thenByDescending { it.registrationDateTime }
)

 

또는 아래와 같이 할수도 있음

// 코드 중 일부
val sortedList = contentsList.sortedWith(compareBy<DisplayCornerContents> {
    when (it.languagesinformation?.contentsDescription) {
        "프로모션" -> 0
        "일반" -> 1
        else -> 2
    }
}.thenBy { it.displaySequence }
    .thenByDescending { it.registrationDateTime })
    .take(NUMBER_TWO)

 

 

728x90