-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
987abcb
commit bf03cbf
Showing
4 changed files
with
43 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# equals를 재정의할 때는 반드시 hashCode도 재정의하라 | ||
|
||
* 많은 버그가 hashCode를 재정의하지 않아서 생긴다. | ||
* **equals 메서드를 재정의한 클래스는 반드시 hashCode 메서드도 재정의햐아한다.** | ||
* 그렇지 않으면 Obejct.hashCode의 일반 규약을 어기게 되므로, HashMap, HastSet, Hasttable 같은 Hash 기반 컬랙샨과 함께 사용된다면 오동작하게된다. | ||
|
||
## Object 클래스 명세 일반 규약 | ||
* 으용프로그램 실행 중에 같은 객체의 hashCode를 여러 번 호출하는 경우, equals가 사용하는 정보들이 변경되지 않았다면, 언제나 동일한 정수가 리턴된다.(프로그램 종료시에는 같은 값이 나올 필요는 없다 ) | ||
* **equals(Object) 메서드가 같다고 판정한 두 객체의 hashCode 값은 같아야한다** | ||
* equals(Object) 메서드가 다르다고 판정한 두 객체의 hashCode 값이 꼭 다를 필요는 없다. 그러나 서로 다른 hashCode 값이 나오면 해시 테이블의 성능이 향상될 수 있다는 점은 이해하고 있어야한다. | ||
|
||
## 핵심 규약 | ||
* **hashCode 재정의하지 않으면 위반되는 핵심 규약은 두 번째다.같은 객체는 같은 해시 코드값을 가 져야한다는 규약이 위반되는 것이다.** | ||
* hashCode를 재정의하지 않을 경우는 equals가 true임에도 서로다른 hashCode를 갖게된다. | ||
* 따라서 Map 컬랙션에서 get메서드는 put 메서드가 객체를 저장한 것과 다른 해시버킷을 뒤지게된다. | ||
* 설사 좋아서 같은 버킷을 뒤지게 되더라도 get 메서드는 항상 null을 리턴한다. HashMap은 성능 최적화를 위해 내부에 보관된 코드를 캐시해 두고, 캐시된 해시 코드가 없다면 객체는 동일성 검사조차 하지 않기 때문이다. | ||
* 그렇다고 모든 객체가 같은 해시 코드를 갖게하는 방법으로 구현하면 안된다. | ||
* 해시 테이블에서 검색하는 시간이 끔찍히 오래 걸리니가(뭐 당연한 이야기) | ||
* 이상적인 해시; 함수는 서로 다른 객체들을 모든 가능한 해시에 값에 균등하게 분배햐야 한다. | ||
* 이런 이상적인 해시 함수에 가까운 함수를 만드는 건 별로 어렵지 않다. | ||
* 알맞는 자료형에 따라서 알고리즘이 달라진다. 결과적으로 나름 균등한 해쉬 값을 갖게하는거 같다. | ||
* 내부적인 알고리즘은 좀 어렵다... 실용적인 방법은 아래 sample code 참조 | ||
* 주의할 것은, 성능 개선을하려고 객체의 중요 부분을 해시 코드 계산 과정에서 생략하면 안된다는 것이다. | ||
* 해시 만드는 것에 로직이 있어 좀 오려 걸려도 해시 품질이 안좋아지면(값이 균등하지 않다면) 해시 기반으로 검색시 느려지기 때문에 결과적으로 더 느려진다는 내용 | ||
|
||
|
||
## Sample Code | ||
```java | ||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# 11 규칙 toString은 항상 재정의하라 | ||
* Object 클래스가 toString을 제공 | ||
* toString 규약 : 사람이 읽기 쉽도록 간략하지만 유용한 정보를 제공해야한다. | ||
* @ + 16진수 표현된 해시코드가 붙은 문자열로 사람이 읽기 쉬운것은 아니다 | ||
* **그래서 모든 하위클래스에서 toString을 재정의함이 바람직하다.** | ||
* toString을 재정의하지 않으면 진단 메시지를 통해서 얻을수 있는 저옵는 거의 없을 것이다. | ||
* 가능하다면 toString 메서드는 객체 내의 중요 정보를 전부 담아 반한해야한다. | ||
* equals, hashCode 규약을 따는 것보다는 덜 중요하다 | ||
* toSring 어떤 의도인지를 주석을 분명하게 남겨야한다 | ||
* toString을 통해서 필요한 비지니스 로직을 수행하기도 하니 말이다. |