2012-07-23 11 views
5

Bei zwei verschiedenen Strings ist es immer der Fall, dass s.GetHashCode() != s1.GetHashCode()?string.GetHashCode() Eindeutigkeit und Kollisionen

Ist die Anzahl der einzelnen ganzen Zahlen kleiner als die Anzahl der einzelnen Zeichenfolgen?

+2

Siehe http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx –

Antwort

12

Nein, nur als ein einfaches Gedankenexperiment: Wie viele Saiten gibt es (Tipp: viel mehr als 2 und damit, wie viele eindeutiger Hash-Codes kann es sein (Tipp:. 2 See the problem?)

Hash-Codes werden nur gleich wann immer Equals kehrt sein erforderlich, dass beide Objekte gleich sind. Außerdem, wenn zwei Hash-Codes nicht gleich, dann sind die Objekte selbst nicht gleich sein können. Es gibt keine weitere Anforderung ist, aber sie sollte so gut verteilt sein dass Hash-Tabellen gut funktionieren können. Also im Grunde ist es:

enter image description here

Notiere die Auslassung der jeweiligen ⇐ Varianten. Es ist keine Äquivalenz, nur zwei Implikationen.

die documentation zitieren:

für jedes Objekt
  1. Wenn zwei Objekte gleich, ist die GetHashCode Methode den gleichen Wert muss zurückgeben:

    Eine Hash-Funktion die folgenden Eigenschaften aufweisen muss. Wenn zwei Objekte jedoch nicht als gleichwertig verglichen werden, müssen die GetHashCode-Methoden für die beiden Objekte keine unterschiedlichen Werte zurückgeben.

  2. Die GetHashCode-Methode für ein Objekt muss konsistent den gleichen Hashcode zurückgeben, solange keine Änderung am Objektzustand vorgenommen wird, der den Rückgabewert der Equals-Methode des Objekts bestimmt. Beachten Sie, dass dies nur für die aktuelle Ausführung einer Anwendung gilt und dass ein anderer Hash-Code zurückgegeben werden kann, wenn die Anwendung erneut ausgeführt wird.

  3. Für die beste Leistung muss eine Hash-Funktion eine zufällige Verteilung für alle Eingaben generieren.

+1

Das Problem, auf das du in deiner Opening-Linie anspielst, ist bekannt als das [Taube-Loch-Prinzip] (http://en.wikipedia.org/wiki/Pigeonhole_Principle) - mehr Tauben, als du Taubenlöcher hast. – RJFalconer

+1

Ich weiß, aber anscheinend könnte nicht jeder Leser, zugegebenermaßen. Ich habe es bearbeitet. – Joey

6

hinzufügen @ Sie Joey Aussage hauptsächlich können die Hashcodes immer ungleich sein nicht haben.

Es gibt 2^32 mögliche Hash-Codes, aber unendliche Eingabezeichenfolgen.

Hash-Kollisionen sind garantiert mit genügend (2^32 + 1) Eingabewerte geschehen.

In der Tat sind Hash-Kollisionen viel häufiger, als man aufgrund der Birthday Problem denken könnte. Als ich die Mathematik vor einer Weile für ein System, das 64-Bit-Hash-Codes verwendet (die Weg mehr mögliche Hash-Werte als 32-Bit-Hash-Codes, nicht nur doppelt, wie man naiv denken könnte) mit 100 Millionen Eingabewerte es war sehr gut möglich, dass es mindestens 1 Hash-Kollision geben würde. Ich denke, die Wahrscheinlichkeit lag bei 1%.

0

Soweit ich weiß Object.GetHashCode() bietet keine Hash-Funktion über das Objekt (so nehme ich an, Joey ist in diesem Fall nicht korrekt), gibt es nur einen eindeutigen Index von CLR das Objekt zugewiesen, wenn das Objekt erstellt und freigegeben, wenn das Objekt Müll gesammelt wird.

Sie können also nicht zu einem bestimmten Zeitpunkt einen Hashcode-Duplikat (in derselben AppDomain) haben, aber Sie könnten ein Duplikat über die Zeit haben (derselbe Index kann während der Anwendungsausführung mehr als einmal vergeben werden).

Die Frage ist auch hier diskutiert: Default implementation for Object.GetHashCode()