Hashcode für eine eindeutige ID verwenden

8

Ich arbeite in einem Java-basierten System, wo ich eine ID für bestimmte Elemente in der visuellen Anzeige festlegen muss. Eine Kategorie von Elementen ist Strings. Daher entschied ich mich, die String.hashCode () -Methode zu verwenden, um eine eindeutige Kennung für diese Elemente zu erhalten.

Das Problem, auf das ich gestoßen bin, ist jedoch, dass das System, in dem ich arbeite, wenn die ID negativ ist und String.hashCode oft negative Werte liefert. Eine schnelle Lösung besteht darin, einfach Math.abs () um den Hashcode-Aufruf zu verwenden, um ein positives Ergebnis zu garantieren. Was ich über diesen Ansatz fragte, ist, was sind die Chancen von zwei verschiedenen Elementen, die den gleichen Hashcode haben?

Wenn beispielsweise ein String einen Hashcode von -10 zurückgibt und ein anderer String einen Hashcode von 10 zurückgibt, tritt ein Fehler auf. In meinem System sprechen wir über Sammlungen von Objekten, die normalerweise nicht mehr als 30 Elemente groß sind, also glaube ich nicht, dass dies wirklich ein Problem wäre, aber ich bin neugierig, was die Mathematik sagt.

    
IcedDante 26.01.2014, 20:01
quelle

4 Antworten

11

Hash-Codes können als Pseudozufallszahlen betrachtet werden. Statistisch gesehen erreicht die Wahrscheinlichkeit einer Kollision zweier Elemente bei einem positiven int Hash-Code 50%, wenn die Populationsgröße etwa 54K beträgt (und 77K für beliebige int ). Siehe Birthday Problem Probability Table für Kollisionswahrscheinlichkeiten verschiedener Hash-Code-Größen.

Auch Ihre Idee, Math.abs() alleine zu verwenden, ist fehlerhaft: Es gibt nicht immer eine positive Zahl zurück! In der Komplementarithmetik von 2 ist der absolute Wert von Integer.MIN_VALUE selbst! In der Regel ist der Hash-Code von "polygenelubricants" dieser Wert.

    
Bohemian 26.01.2014, 20:14
quelle
6

Hashes sind nicht eindeutig, daher sind sie für uniqueId nicht geeignet.

Was die Wahrscheinlichkeit einer Hash-Kollision angeht, könntest du über Geburtstagsparadox nachlesen. Tatsächlich (was ich mich erinnere), wenn man aus einer gleichmäßigen Verteilung von N Werten zeichnet, sollte man nach dem Zeichnen von $ \ sqrt (N) $ mit einer Kollision rechnen (man könnte die Kollision viel früher bekommen). Das Problem ist, dass die Java-Implementierung von hashCode (und speziell beim Hashing von kurzen Strings) keine einheitliche Verteilung bietet, so dass Sie die Kollision viel früher bekommen.

    
jb. 26.01.2014 20:13
quelle
3

Sie können bereits zwei Strings mit demselben Hashcode erhalten. Dies sollte offensichtlich sein, wenn Sie denken, dass Sie eine unendliche Anzahl von Strings und nur 2 ^ 32 mögliche Hashcodes haben.

Sie machen es nur etwas wahrscheinlicher, wenn Sie den absoluten Wert nehmen. Das Risiko ist gering, aber wenn Sie eine eindeutige ID benötigen, ist dies nicht der richtige Ansatz.

    
Denys Séguret 26.01.2014 20:04
quelle
1

Was Sie tun können, wenn Sie nur 30-50 Werte haben, wie Sie gesagt haben, registrieren Sie jeden String, den Sie in eine HashMap zusammen mit einem laufenden Zähler als Wert erhalten:

%Vor%

Sie können dann Ihre eindeutige ID erhalten, indem Sie Folgendes aufrufen:

%Vor%     
Dakkaron 26.01.2014 20:48
quelle

Tags und Links