web-dev-qa-db-ja.com

負の値を与えるHashCode

次の関数を実行することにより、入力文字列をハッシュコードに変換していますが、一部の値が負です。ハッシュ値が負であるべきだとは思わない。私が間違っていることを教えてください。

int combine = (srcadd + dstadd + sourceport + destinationport + protocol).hashCode();
System.out.println(combine);
27
Xara

ハッシュ値が負であるべきだとは思わない。

何故なの?負のハッシュコードを使用することは完全に有効です。ハッシュコードを作成するほとんどの方法は、自然に負の値になるため、それらを扱うものはすべてこれを考慮する必要があります。ただし、ハッシュコードを作成するための別のアプローチを検討します。

int hash = 17;
hash = hash * 31 + srcadd.hashCode();
hash = hash * 31 + dstadd.hashCode();
hash = hash * 31 + sourceport; // I'm assuming this is an int...
hash = hash * 31 + destinationport; // ditto
hash = hash * 31 + protocol.hashCode();
return hash;

これらの式の種類が明確ではありませんが、文字列のハッシュコードを取得することになっていると思います。最初に作成する必要のない文字列です。既知のドメインのハッシュコードを取得するためのより良いアプローチがありますが、上記のアプローチは汎用のハッシュ生成手法としてうまく機能します。

略語を避け、キャメルケースを使用すると、コードが読みやすくなることに注意してください。 sourceAddressの代わりにsrcadd

41
Jon Skeet

時々hashcode計算自体がInteger.MAX_VALUE、つまり2147483647。そうなると、overflowの後に負の整数が得られます。 負のハッシュコードは完全に有効です!

24
Pravat Panda

負のハッシュコード、およびハッシュ値を探している場合は、完全に合法ですハッシュベースのコレクションで使用されるように、Math.abs(hash)を使用できます。これは、ハッシュが2 ^ 31より大きいときに負の数を与えることもあります。最良の方法は、シフトマスク(key.hashCode() & 0x7fffffff) % Mを使用することです。ここで、Mはテーブルサイズです。

12
Milky