この質問にはすでに答えがあります。
私は尋ねました似たような質問のためにstring.GetHashCode()
.NETのメソッドです。それから、私たちが異なるマシンにまたがってそれを使うのであれば、私たちは組み込み型のハッシュコードの暗黙の実装に頼ることができないことを学びました。したがって、私はJavaの実装はString.hashCode()
ハードウェア構成が異なると不安定になり、VMが異なると動作が異なる可能性があります(異なるVMの実装を忘れないでください)。
現在、ハッシュによってJavaで文字列を安全に数値に変換する方法を検討していますが、ハッシュアルゴリズムはクラスタの異なるノード間で安定している必要があり、使用頻度が高くなるため、評価を早くする必要があります。私のチームメイトはネイティブを主張していますhashCode
他のアプローチを再考するためには、いくつかの合理的な議論が必要です。現時点では、マシン構成(x86とx64)、おそらくマシンによってはJVMのベンダーが異なる(私たちの場合はほとんど当てはまりません)、およびアルゴリズムが実行されているマシンに応じたバイトオーダーの違いの違いしか考えられません。走る。もちろん、文字エンコーディングもおそらく考慮されるべきです。
これらすべてのことが私の頭に浮かぶのですが、私はそれらのどちらかが100%確実な理由で十分であると確信しているわけではありません。これは私がカスタムハッシュアルゴリズムを書くことを支持するためにより強い議論を構築するのを助けるでしょう。また、私は何についてのアドバイスをお願い申し上げますしない実装時
の実装String.hashCode()
です指定されたドキュメントの中では、一貫性があることが保証されています。
Stringオブジェクトのハッシュコードは、次のように計算されます。
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
ここで、s [i]は文字列のi番目の文字、nは文字列の長さ、^は指数を表します。 (空の文字列のハッシュ値はゼロです。)
これらの操作はすべて、Java用にプラットフォームに依存せずに実装されています。たとえば、プラットフォームのバイト順は関係ありません。
とはいえ、取得あるString
ファイルや別のバイトのソースから取得する場合は、注意が必要です。その場合は、明示的に指定すれば問題ありません。Charset
。 (覚えているString
sそれ自体は異なるエンコーディングを持っていません。エンコーディングはコンバージョン〜の間byte[]
そしてString
。)
あなたは見ることができます以下に示すソースコード。私が見ることができるもの(10秒の分析のすべての後)から、これはマシンとアーキテクチャの間で安定しているはずです。そして、Louisはこれをスペックを引用することで確認しています。 :-)
ただし、異なるJREが異なる方法で実装し、仕様に違反することを選択した場合、これは異なる可能性があります。
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
String#hashCode
。 - Luiggi MendozaString
クラスは、それは十分に安定して見えます。しかし、.NETでそうなることがあるので、それに頼らない理由があります。仮想マシン、ハードウェアの違い、バイト順やエンコードの種類などを考慮すると、Javaのケースは私に非常に似ているようです。 - Ivaylo Slavov