From bf03cbffe430013bc94876ba2b40476e5fa40ca9 Mon Sep 17 00:00:00 2001 From: Yun Date: Thu, 7 Jun 2018 02:31:54 +0900 Subject: [PATCH] =?UTF-8?q?Effective=20java=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Effective-Java/03/Comparable.md | 0 Effective-Java/03/clone.md | 0 Effective-Java/03/hashCode.md | 33 +++++++++++++++++++++++++++++++++ Effective-Java/03/toString.md | 10 ++++++++++ 4 files changed, 43 insertions(+) create mode 100644 Effective-Java/03/Comparable.md create mode 100644 Effective-Java/03/clone.md diff --git a/Effective-Java/03/Comparable.md b/Effective-Java/03/Comparable.md new file mode 100644 index 0000000..e69de29 diff --git a/Effective-Java/03/clone.md b/Effective-Java/03/clone.md new file mode 100644 index 0000000..e69de29 diff --git a/Effective-Java/03/hashCode.md b/Effective-Java/03/hashCode.md index e69de29..b0cf9aa 100644 --- a/Effective-Java/03/hashCode.md +++ b/Effective-Java/03/hashCode.md @@ -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); +} +``` \ No newline at end of file diff --git a/Effective-Java/03/toString.md b/Effective-Java/03/toString.md index e69de29..a170db5 100644 --- a/Effective-Java/03/toString.md +++ b/Effective-Java/03/toString.md @@ -0,0 +1,10 @@ +# 11 규칙 toString은 항상 재정의하라 +* Object 클래스가 toString을 제공 + * toString 규약 : 사람이 읽기 쉽도록 간략하지만 유용한 정보를 제공해야한다. + * @ + 16진수 표현된 해시코드가 붙은 문자열로 사람이 읽기 쉬운것은 아니다 +* **그래서 모든 하위클래스에서 toString을 재정의함이 바람직하다.** + * toString을 재정의하지 않으면 진단 메시지를 통해서 얻을수 있는 저옵는 거의 없을 것이다. + * 가능하다면 toString 메서드는 객체 내의 중요 정보를 전부 담아 반한해야한다. + * equals, hashCode 규약을 따는 것보다는 덜 중요하다 + * toSring 어떤 의도인지를 주석을 분명하게 남겨야한다 + * toString을 통해서 필요한 비지니스 로직을 수행하기도 하니 말이다.