次の関数を実行して、着信文字列をハッシュ コードに変換していますが、一部の値が負です。ハッシュ値が負であってはならないと思います。私が間違っていることを教えてください。
int combine = (srcadd + dstadd + sourceport + destinationport + protocol).hashCode();
System.out.println(combine);
次の関数を実行して、着信文字列をハッシュ コードに変換していますが、一部の値が負です。ハッシュ値が負であってはならないと思います。私が間違っていることを教えてください。
int combine = (srcadd + dstadd + sourceport + destinationport + protocol).hashCode();
System.out.println(combine);
ハッシュ値が負であってはならないと思います。
なぜだめですか?負のハッシュ コードを持つことは完全に有効です。ハッシュ コードを作成する方法のほとんどは、自然に負の値になります。負の値を扱う場合は、これを考慮する必要があります。ただし、ハッシュコードを思いつくための別のアプローチを検討します。
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
。
時には、計算hashcode
自体が を超えることがあります。次に何が起こるかというと、 の後に負の整数が得られます。負のハッシュコードは完全に有効です!Integer.MAX_VALUE
2147483647
overflow
負のハッシュ コードを持つことは完全に合法であり、ハッシュ ベースのコレクションで使用されるハッシュ値を探している場合は、 を使用できますMath.abs(hash)
。これにより、ハッシュが 2^31 より大きい場合にも負の数が返される可能性があります。最善の方法は、シフト マスクを使用すること(key.hashCode() & 0x7fffffff) % M
です。ここで、M はテーブル サイズです。