1

私は現在 Cocoa コレクションを研究しており、私の研究はオブジェクトの等価性とハッシュに関するMike Ash の投稿につながりました。

投稿からの抜粋は次のとおりです。

ハッシュのセマンティクスのため、isEqual: をオーバーライドする場合は、ハッシュをオーバーライドする必要があります。そうしないと、等しいが同じハッシュを持たない 2 つのオブジェクトを持つリスクがあります。これらのオブジェクトをディクショナリ、セット、またはハッシュ テーブルを使用するその他のもので使用すると、陽気になります。

残念ながら、著者は何が起こるのかについて詳しく説明しておらず、私の好奇心は、より深く掘り下げようとせずにそのままにしておくことを許しません. 問題は、ハッシュ値が異なる 2 つの等しいオブジェクトがあり、これらのオブジェクトを 1 つのコレクションに入れると、正確にはどうなるかということです。どのような問題に遭遇しますか?

4

2 に答える 2

5

答えは、マイクの投稿のこのセクションにあります

ハッシュ テーブルは基本的に、特別なインデックスを持つ大きな配列です。オブジェクトは、そのハッシュに対応するインデックスを持つ配列に配置されます。ハッシュは基本的に、オブジェクトのプロパティから生成される疑似乱数です。アイデアは、2 つのオブジェクトが同じハッシュを持つ可能性が低くなるようにインデックスを十分にランダムにすることですが、完全に再現可能にすることです。オブジェクトが挿入されると、ハッシュを使用してオブジェクトの移動先が決定されます。オブジェクトが検索されると、そのハッシュを使用してどこを検索するかが決定されます。

より正式な用語では、オブジェクトのハッシュは、2 つのオブジェクトが等しい場合に同一のハッシュを持つように定義されます。逆は当てはまらないことに注意してください。つまり、2 つのオブジェクトが同一のハッシュを持ち、等しくない可能性があります。2 つの等しくないオブジェクトが同じハッシュを持つ (衝突と呼ばれる) 場合、ハッシュ テーブルはこれを処理するために特別な手段を講じる必要があり、処理が遅くなるため、これをできるだけ回避する必要があります。ただし、完全に回避することはおそらく不可能です。

それが意味することは、等しいと主張する 2 つのオブジェクトがあるということです。最初の値をディクショナリのキーとして追加します。次に、他のオブジェクトをキーとして使用してその値を抽出しようとします。そして、それは機能しません。オブジェクトが等しいため、そうする必要があります。しかし、最初のハッシュ ルックアップは失敗しました。

明確にするために、これは起こらないかもしれません。一部のオブジェクトでは正常に機能し、他のオブジェクトでは失敗する場合があります。ポイントは、両方の方法を実装しないと、何が起こるかわからないということです。

于 2013-04-13T09:03:38.230 に答える
0

「理由」を知りたいという欲求はさておき、Apple のドキュメントを参照してください。

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html%23//apple_ref/occ/intfm/NSObject/isKindOfClass :

If two objects are equal, they must have the same hash value.

他のすべての議論は学術的な観点からは興味深いものですが、基本的に Apple の規則に同意するかどうかに関係なく、財団のフレームワークを使用する場合はそれらに従う必要があります。

マイクと上記のポスターが言っていることは、現在の NSDictionary の化身にとって真実であるように思われます - 同じ実装が将来のリリースでそのまま残るという保証はありません。ただし、Apple がそれをどのようなものに置き換えても、(おそらく) 同じ保証と制限がすべて保持されます。

于 2013-04-13T23:59:50.740 に答える