[解決済み] Java の String の hashCode() では、なぜ 31 が乗数として使われるのですか?
2022-03-19 03:45:22
質問
Java のドキュメントによると
ハッシュコード
に対して
String
オブジェクトは次のように計算されます。
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
を使って
int
の算術演算を行い、ここでs[i]
は i の文字が含まれる。n
は長さ 文字列、および^
は指数を示す。
なぜ31が乗数として使われるのですか?
乗数は比較的大きな素数であるべきだと理解しています。では、なぜ29や37、あるいは97でないのか?
解き方は?
ジョシュア・ブロッホの 効果的なJava (この本はあまりお勧めできない本で、stackoverflowで何度も言及されているおかげで購入しました)。
<ブロッククオート
31という値が選ばれたのは、奇数素数だからです。もし偶数で、掛け算がオーバーフローした場合、2の掛け算はシフトと同じなので、情報が失われてしまうからです。素数を使うメリットはあまり明確ではないが、伝統的なものである。31の良い特性は、掛け算をシフトと引き算に置き換えて、パフォーマンスを上げることができることです。
31 * i == (i << 5) - i
. 最近のVMはこのような最適化を自動で行ってくれます。
(第3章 項目9: equals を上書きするときは必ずハッシュコードを上書きする、48ページより)
関連
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] どうすれば、文字列中のリテラルな中抜き文字を印刷し、また.formatを使用することができるのでしょうか?
-
[解決済み] なぜlist.join(string)ではなくstring.join(list)なのでしょうか?
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み] なぜゲッターとセッター/アクセッサーを使うのですか?
-
[解決済み] なぜJavaにはtransientフィールドがあるのですか?
-
[解決済み] Stringでswitch文が使えないのはなぜですか?
-
[解決済み】なぜJavaの+=, -=, *=, /=複合代入演算子はキャスティングを必要としないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java Exceptionが発生しました エラー解決
-
JDKの設定時にjava.dllが見つからない、java SE Runtime Environmentが見つからない問題が発生しました。
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
スレッド "main" で例外発生 java.net.BindException: アドレスは既に使用中です。NET_Bind
-
java 例外。Javaツールの初期化
-
このラインで複数のマーカーを解決する方法
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について
-
[解決済み] ハッシュコードとチェックサム、その違いは?
-
[解決済み] なぜハッシュ関数には素数モジュールが必要なのですか?
-
[解決済み] なぜhashCodeに素数を使うのですか?