Search

Equality

Kotlin에서 동등성에는 두 가지 유형이 있다.

구조적 동등성(Structural Equality)

구조적 동등성은 두 객체의 내용이나 구조가 동일한지를 검증한다.
구조적 동등성은 == 연산자와 그 반대인 != 로 확인된다.
a?.equals(b) ?: (b === null)
Kotlin
복사
a == b 는 위처럼 변환된다.
a가 null이 아닐 경우 equals(Any?) 함수를 호출하고 a가 null인 경우 b가 null과 참조적으로 같은지 확인한다.
fun main() { var a = "hello" var b = "hello" var c = null var d = null var e = d println(a == b) // true println(a == c) // false println(c == e) // true }
Kotlin
복사
null을 명시적으로 비교할 때 a == null 은 자동으로 a === null 로 변환되므로 코드 최적화가 필요없다.
class Point(val x: Int, val y: Int) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Point) return false // 구조적 동등성을 위해 속성 비교 return this.x == other.x && this.y == other.y } }
Kotlin
복사
Kotlin에서 equals() 함수는 모든 클래스에 Any 클래스로부터 상속된다.
기본적으로 equals() 함수는 참조적 동등성을 구현하므로 equals() 함수를 오버라이드하여 구조적 동등성을 구현할 수 있다.
값 클래스와 데이터 클래스는 equals() 함수를 자동으로 오버라이드하여 제공하며 기본적으로 구조적 동등성을 구현한다.
데이터 클래스의 경우 부모 클래스에서 equals() 함수가 final로 지정된 경우 동작이 변하지 않는다.
equals() 함수를 오버라이드 하려면 equals(other: Any?): Boolean 함수를 오버라이드해야 하며 같은 이름이지만 다른 시그니처를 가진 함수는 동등성 검사에 영향을 미치지 않는다.
Comparable<…> 인터페이스에 의해 정의된 비교는 동등성 연산자의 동작에 영향을 주지 않는다.

참조적 동등성(Referential Equality)

참조적 동등성은 두 객체의 메모리 주소를 검증하여 같은 인스턴스인지 확인한다.
참조적 동등성은 === 연산자와 그 반대인 !== 로 확인한다.
fun main() { var a = "Hello" var b = a var c = "world" var d = "world" println(a === b) // true println(a === c) // false println(c === d) // true }
Kotlin
복사
Int 처럼 런타임에 원시 타입으로 표현되는 값의 경우 === 검사는 == 검사와 동일하다.
Kotlin/JS 에서는 참조적 동등성이 다르게 구현된다.

부동 소수점 숫자의 동등성

정적으로 부동 소수점 숫자로 타입(Float 또는 Double)이 지정된 피연산자
동등성 검사는 IEEE 754 표준에 따른 부동 소수점 산술을 따른다.
정적으로 부동 소수점 숫자로 타입(Float 또는 Double)이 지정되지 않은 피연산자
구조적 동등성이 구현된다.
동등성 검사는 IEEE 표준과 다르다.
1.
NaN은 자기 자신과 같다고 평가
2.
NaN은 다른 모든 요소(POSITIVE_INFINITY 등)보다 큼
3.
-0.0 은 0.0 과 같지 않음

배열의 동등성

두 배열이 동일한 요소를 같은 순서로 갖는지 비교하려면 contentEquals() 를 사용하라.