hashCode 및 == 오버라이드
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 71번째.
기본적으로 Dart에서 두 객체는 메모리 상에서 정확히 동일한 인스턴스인 경우에만 동일한 것으로 간주됩니다. 즉, 동일한 값을 가진 두 객체라도 여전히 서로 다른 것으로 간주됩니다:
class Point {
int x, y;
Point(this.x, this.y);
}
void main() {
var p1 = Point(3, 4);
var p2 = Point(3, 4);
print(p1 == p2); // false - 서로 다른 인스턴스입니다!
}객체를 값으로 비교하려면 == 연산자와 hashCode를 모두 재정의해야 합니다. 이 두 가지는 항상 함께 재정의되어야 합니다. 두 객체가 같다면, 반드시 동일한 해시 코드를 가져야 합니다:
class Point {
final int x, y;
Point(this.x, this.y);
@override
bool operator ==(Object other) {
if (other is! Point) return false;
return x == other.x && y == other.y;
}
@override
int get hashCode => Object.hash(x, y);
}
void main() {
var p1 = Point(3, 4);
var p2 = Point(3, 4);
print(p1 == p2); // true - 값이 같습니다!
}hashCode는 Set 및 Map 키와 같은 컬렉션에 매우 중요합니다. Dart의 Object.hash() 헬퍼는 여러 값을 단일 해시 코드로 결합합니다. 적절한 hashCode가 없으면 ==가 재정의되더라도 객체가 해시 기반 컬렉션에서 올바르게 작동하지 않습니다.
챌린지
쉬움메모리 주소가 아닌 값에 의해 포인트를 비교할 수 있는 좌표 시스템을 만들어 봅시다! 값 기반의 동등성(equality)을 올바르게 구현하는 Coordinate 클래스를 생성하여, 동등성 검사 및 Set과 같은 해시 기반 컬렉션에서 올바르게 작동하도록 만들 것입니다.
코드를 두 개의 파일로 구성합니다:
coordinate.dart:final int x와final int y필드를 가진 2D 공간의 점을 나타내는Coordinate클래스를 생성합니다. 동일한 x 및 y 값을 가진 두 좌표가 동일한 것으로 간주되도록==연산자와hashCode를 모두 오버라이드합니다. 두 필드로부터 해시 코드를 생성하기 위해Object.hash()를 사용하세요.main.dart: coordinate 파일을 임포트하고 값 기반 동등성이 객체 비교 동작을 어떻게 바꾸는지 보여줍니다:- x:
5, y:10인 두 개의 별개Coordinate객체를 생성합니다. ==를 사용하여 두 객체가 같은지 출력합니다.identical()을 사용하여 두 객체가 동일한 인스턴스인지 출력합니다.Set<Coordinate>를 생성하고 두 좌표를 모두 추가합니다.- 세트의 길이를 출력합니다 (두 객체가 같으므로 1이어야 합니다!).
- x:
3, y:7인 세 번째 좌표를 생성하여 세트에 추가합니다. - 세트의 최종 길이를 출력합니다.
- x:
이 챌린지는 왜 hashCode와 ==를 항상 함께 오버라이드해야 하는지 보여줍니다. Set은 요소를 구성하기 위해 해시 코드를 사용하므로, 적절한 hashCode가 없으면 동일한 객체라도 중복으로 저장될 수 있습니다!
예상 출력:
true
false
1
2치트 시트
기본적으로 Dart에서 두 객체는 메모리상의 동일한 인스턴스인 경우에만 동일하며, 단순히 값이 같다고 해서 동일한 것으로 간주되지 않습니다:
var p1 = Point(3, 4);
var p2 = Point(3, 4);
print(p1 == p2); // false - different instances!객체를 값으로 비교하려면 == 연산자와 hashCode를 모두 오버라이드해야 합니다. 이들은 항상 함께 오버라이드되어야 합니다:
class Point {
final int x, y;
Point(this.x, this.y);
@override
bool operator ==(Object other) {
if (other is! Point) return false;
return x == other.x && y == other.y;
}
@override
int get hashCode => Object.hash(x, y);
}여러 값을 하나의 해시 코드로 결합하려면 Object.hash()를 사용하세요. hashCode는 Set이나 Map과 같은 컬렉션에서 매우 중요합니다. 이것이 없으면 동일한 객체들이 해시 기반 컬렉션에서 올바르게 작동하지 않습니다.
두 객체가 (단순히 값이 같은 것이 아니라) 동일한 인스턴스인지 확인하려면 identical()을 사용하세요:
print(identical(p1, p2)); // false - different instances직접 해보기
import 'coordinate.dart';
void main() {
// TODO: x: 5, y: 10을 가진 두 개의 서로 다른 Coordinate 객체를 생성하세요
// TODO: ==를 사용하여 두 객체가 같은지 여부를 출력하세요
// TODO: identical()을 사용하여 두 객체가 동일한지(같은 인스턴스인지) 여부를 출력하세요
// TODO: Set<Coordinate>를 생성하고 두 좌표를 모두 추가하세요
// TODO: 세트의 길이를 출력하세요 (두 객체가 같으므로 1이어야 합니다!)
// TODO: x: 3, y: 7인 세 번째 좌표를 생성하고 세트에 추가하세요
// TODO: 세트의 최종 길이를 출력하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.