코틀린 & Java/코틀린인액션

Kotlin == 비교연산자 오버로딩

코딩하는후운 2023. 5. 9. 13:24
반응형

비교연산자 오버로딩

  • equals, compareTo 대신 Kotlin 에서는 == 비교 연산자를 사용할 수 있음

equals

  • == 연산자는 equals 메서드 호출로 컴파일된다.
  • a==b → a?.equals(b) ?: (b==null)
val USE_KAKAO_ACCOUNT_LOGIN = env.name == "DEV"

// Decompiled
static {
	USE_KAKAO_ACCOUNT_LOGIN = Intrinsics.areEqual(env.name(), "DEV");
}

// ----------------------------------

val USE_KAKAO_ACCOUNT_LOGIN = env.name === "DEV"

// Decompiled 하면?
 env.name == "DEV"

https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java

 

GitHub - JetBrains/kotlin: The Kotlin Programming Language.

The Kotlin Programming Language. . Contribute to JetBrains/kotlin development by creating an account on GitHub.

github.com

  • === 연산자 : 식별자 비교
  • 서로 같은 객체를 가리키는가? (프리미티브인 경우 두 값이 같은가)
class Point(val x: Int, val y:Int) 
	override fun equals(obj: Any?): Boolean {
		if (obj === this) return
		if (obj !is Point) return false
		return obj.x == x && obj.y == y
  }
}
  • 식별자 비교는 equals 를 구현할때 자기 자신과의 비교를 최적화 하기 위해 사용한다.
  • 식별자 비교 === 는 오버라이딩 할 수 없다.

CompareTo

  • Kotlin Comparable Interface 에 있는 compareTo 메소드 관례
  • a > = b → a.compareTo(b) ≥ 0
class Person(
    val firstName: String, val lastName: String
): Comparable<Person> {
    override fun compareTo(other: Person): Int {
        return compareValuesBy(this, other, Person::lastName, Person:: firstName)
    }
}

-----------------------------------------------------------------------

/**
 * Classes which inherit from this interface have a defined total ordering between their instances.
 */
public interface Comparable<in T> {
    /**
     * Compares this object with the specified object for order. Returns zero if this object is equal
     * to the specified [other] object, a negative number if it's less than [other], or a positive number
     * if it's greater than [other].
     */
    public operator fun compareTo(other: T): Int
}

------------------------------------------------------------------
/**
 * Compares two values using the specified functions [selectors] to calculate the result of the comparison.
 * The functions are called sequentially, receive the given values [a] and [b] and return [Comparable]
 * objects. As soon as the [Comparable] instances returned by a function for [a] and [b] values do not
 * compare as equal, the result of that comparison is returned.
 *
 * @sample samples.comparisons.Comparisons.compareValuesByWithSelectors
 */
public fun <T> compareValuesBy(a: T, b: T, vararg selectors: (T) -> Comparable<*>?): Int {
    require(selectors.size > 0)
    return compareValuesByImpl(a, b, selectors)
}

private fun <T> compareValuesByImpl(a: T, b: T, selectors: Array<out (T) -> Comparable<*>?>): Int {
    for (fn in selectors) {
        val v1 = fn(a)
        val v2 = fn(b)
        val diff = compareValues(v1, v2)
        if (diff != 0) return diff
    }
    return 0
}


------------------------------------------------------------------ 

/**
 * The `String` class represents character strings. All string literals in Kotlin programs, such as `"abc"`, are
 * implemented as instances of this class.
 */
public class String : Comparable<String>, CharSequence {
    companion object {}
    
...

    @kotlin.internal.IntrinsicConstEvaluation
    public override fun compareTo(other: String): Int

String 의 compareTo

두 문자열에서 각 각 하나하나 씩 Character형으로 변환해 ASCII 코드로 비교하는 방식이며 모든 문자의 차이가 0이 나오는 경우(문자열의 차이가 없는 경우) 0을 반환하고 하나라도 차이가 있다면 그 자리에서 break를 걸어 그 차이만큼을 반환해준다. 선행 문자의 차이는 없는데, 문자열 길이의 차이가 있는 경우 길이의 차이만큼 반환해준다.

abc < bcd 1

반응형