ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 42장 - compareTo 규약을 지켜라
    Kotlin/Effective Kotlin 요약 2023. 4. 5. 00:01

    compareTo 메서드

    compareTo는 Any클래스에 있는 메서드는 아닙니다.

     

    수학적인 부등식으로 변환되는 연산자입니다.

    fun main() {
        val str1 = "a"
        val str2 = "b"
        println(str1 > str2) //str1.compareTo(str2) > 0
        println(str1 < str2) //str1.compareTo(str2) < 0
        println(str1 >= str2) //str1.compareTo(str2) >= 0
        println(str1 <= str2) //str1.compareTo(str2) <= 0
        //false
        //true
        //false
        //true
    }

    어떤 객체가 Comparable <T> 인터페이스를 구현하거나 compareTo라는 연산자 메서드를 가지고 있습니다.

    이는 해당 객체가 어떤 순서를 가지고 있으며 비교할 수 있음을 의미합니다.

     

    compareTo의 동작

    • 비대칭적 동작
      • a >=b 이고 b >= a 라면 a==b이어야 한다.
    • 연속적 동장
      • a >=b 이고 b>=c 라면 a>=c여야 한다. 그렇지 않다면 무한 반복에 빠질 수 있다.
    • 코네스적 동작
      • 두 요소는 확실한 관계를 가지고 있어야 합니다. a>=b 또는 b>=a 중에 적어도 하나는 true여야 합니다.

     

    compareTo의 정의

    일반적으로 특정 프로퍼티 하나를 기반으로 순서를 지정하는 것으로 충분하기 때문에 compareTo를 따로 정의해야 하는 상황은 거의 없습니다.

     

    data class SortTest(
        val name: String,
        val surName: String,
    ){
        companion object{
            val SURNAME_ORDER = compareBy(SortTest::surName)
        }
    }
    
    fun main() {
        val names = listOf(SortTest("a","b"),SortTest("b","a"))
        val sortedByName = names.sortedBy { it.name }
    
        val sortedMultiple = names.sortedWith(compareBy({it.name}, {it.surName}))
        println(sortedByName)
        println(sortedMultiple)
        println(names.sortedWith(SortTest.SURNAME_ORDER))
    }

    특정 프로퍼티에 대해 sortedBy를 활용할 수 있습니다.

    여러 개의 프로퍼티에 대해 compareBy를 사용할 수 있습니다.

    자주 사용한다면 클래스에 companion 객체로 만들어 두는 것도 좋습니다.

     

    compareTo 구현하기

    compareValues 함수 사용해서 비교하기

    data class SortTest(
        val name: String,
        val surName: String,
    ): Comparable<SortTest>{
        override fun compareTo(other: SortTest): Int {
            return compareValues(surName, other.surName)
        }
    }
    
    fun main() {
        val names = listOf(SortTest("b","b"),SortTest("a","a"))
        println(names.sorted())
    }

     

    더 많은 값을 비교하기 위해서는 compareValuesBy를 사용할 수 있습니다.

    data class SortTest(
        val name: String,
        val surName: String,
    ): Comparable<SortTest>{
        override fun compareTo(other: SortTest): Int {
            return compareValuesBy(this, other, {it.surName}, {it.name})
        }
    }
    
    fun main() {
        val names = listOf(SortTest("b","b"),SortTest("a","a"))
        println(names.sorted())
    }

     

     

     

    댓글

Designed by Tistory.