回答編集履歴

3

誤解を生みそうな表現を訂正

2018/06/10 15:44

投稿

swordone
swordone

スコア20651

test CHANGED
@@ -28,7 +28,7 @@
28
28
 
29
29
  実際は10000など大きな数を格納する際に、配列を10000以上のサイズにしたりはせず、その数字に何らかの手を加えて格納する場所を決定します。例えば「10で割った余り」にするなどで。
30
30
 
31
- 重要なのは、**数とルールが決まれば、配列内にある要素が入る場所は一意に決まる**ということです。
31
+ 重要なのは、**数とルールが決まれば、ある要素が配列内に入る場所は一意に決まる**ということです。
32
32
 
33
33
  実際には同じ場所に格納しようとする複数の要素が発生する(シノニム)のですが、その対処法はここでは割愛します(基本情報技術者試験にも出てくる話です)。
34
34
 

2

オーバーライドしなかった場合の不具合についての説明

2018/06/10 15:44

投稿

swordone
swordone

スコア20651

test CHANGED
@@ -46,11 +46,31 @@
46
46
 
47
47
  というわけです。この「一意な整数に変換する」メソッドが`hashCode()`なのです。
48
48
 
49
- HashSetは要素を挿入しようとするとき、格納場所を`hashCode()`の返り値から決定し、存在を確認するのです。これが`equals()`と連動しない結果になっていると、HashSetは正しく動作できないのです。
49
+ HashSetは要素を挿入しようとするとき、格納場所を`hashCode()`の返り値から決定し、存在を確認するのです。
50
50
 
51
51
 
52
52
 
53
+ ### `hashCode()`をオーバーライドしなかった場合
53
54
 
55
+ `hashCode()`が`equals()`と連動しない結果を返すと、HashSetは正しく動作できないのです。`equals()`で等しいとされる2つのオブジェクトAとBが異なる`hashCode()`を返した場合、
56
+
57
+ - まずAを空のSetに入れようとする。Aの`hashCode()`から格納場所がaと計算される。
58
+
59
+ もちろんaには何もないのでAはSetに入る。
60
+
61
+ - 次にBを同じSetに入れようとする。Bの`hashCode()`から格納場所がbと計算される。
62
+
63
+ **bには何もない(Aが入った場所とは異なるため)**ので、BはSetに入る
64
+
65
+
66
+
67
+ というように、1つのSetに等しい要素が2つ入ってしまい、仕様を満たせなくなってしまいます。
68
+
69
+ デフォルトの`hashCode()`が、(雑に説明するなら)コンピュータがオブジェクトごとに割り振った数値を返す仕組みなので、このような事態が起きえます。
70
+
71
+
72
+
73
+ ##### ということで
54
74
 
55
75
  書籍に書いてあったという
56
76
 

1

参考書籍の文言

2018/06/10 15:41

投稿

swordone
swordone

スコア20651

test CHANGED
@@ -47,3 +47,15 @@
47
47
  というわけです。この「一意な整数に変換する」メソッドが`hashCode()`なのです。
48
48
 
49
49
  HashSetは要素を挿入しようとするとき、格納場所を`hashCode()`の返り値から決定し、存在を確認するのです。これが`equals()`と連動しない結果になっていると、HashSetは正しく動作できないのです。
50
+
51
+
52
+
53
+
54
+
55
+ 書籍に書いてあったという
56
+
57
+ > equalsはhashCode()を使用するので同様にオーバーライドする必要がある
58
+
59
+
60
+
61
+ というのは少なくともそのままの意味としては誤りです。