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