39

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

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

3 に答える 3

59

ハッシュ値が負であってはならないと思います。

なぜだめですか?負のハッシュ コードを持つことは完全に有効です。ハッシュ コードを作成する方法のほとんどは、自然に負の値になります。負の値を扱う場合は、これを考慮する必要があります。ただし、ハッシュコードを思いつくための別のアプローチを検討します。

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

于 2012-02-12T15:32:29.357 に答える
40

時には、計算hashcode自体が を超えることがあります。次に何が起こるかというと、 の後に負の整数が得られます。負のハッシュコードは完全に有効です!Integer.MAX_VALUE2147483647overflow

于 2013-07-30T11:46:19.647 に答える
23

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

于 2013-11-29T23:30:19.880 に答える