- PR -

HashMapにて異なるキーが同じ要素に書き込まれます。

1
投稿者投稿内容
K2
会議室デビュー日: 2002/12/19
投稿数: 7
投稿日時: 2005-07-26 16:55
みなさんはじめまして

WindowsXp Pro Sp2
Eclipse 3.0.1
SDK 1.4.2.05

の環境です。

HashMapを利用して、キーと値をセットしています。
文字列がキーなのですが、キーの値が違うにもかかわらず、
同じ要素に書き込まれてしまいます。

Map params = new HashMap();;

params.put("SHIIRESAKI_CD", "00000001");
params.put("NONYUSAKI_CD", "00000002");
params.put("SYOHIN_TANKA_CD", "00000003");
params.put("START_YMD", "1985/10/01");




上記のように値をセットしたときに、変数の値を確認すると
2番目にセットした要素に書き込まれていました。
以下、変数の内容です。

[3]= HashMap$Entry (ID=5829)
hash= -329363325
key= "START_YMD"
next= HashMap$Entry (ID=5833)
hash= 1887899603
key= "NONYUSAKI_CD"
next= null
value= "00000002"
value= "1985/10/01"

のようにセットされてしまいます。
4番目にセットした"START_YMD"のキー値を変えると、
他の要素にセットされます。
ただ、データベースのフィールドと関連づけているので、
名前の変更もままなりません。

何が原因なのでしょうか?
回避策があれば、ヒントでもいただけると助かります。
よろしくお願いいたします。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-07-26 17:27
変ですね。私の環境では期待通り動きますが。
コード:

$ cat Test.java
public class Test{
public static void main(String[] args){
java.util.Map params = new java.util.HashMap();;
params.put("SHIIRESAKI_CD", "00000001");
params.put("NONYUSAKI_CD", "00000002");
params.put("SYOHIN_TANKA_CD", "00000003");
params.put("START_YMD", "1985/10/01");
System.out.println("params:"+params);
System.out.println("size:"+params.size());
}
}
$ javac Test.java
$ java Test
params:{SYOHIN_TANKA_CD=00000003, START_YMD=1985/10/01, NONYUSAKI_CD=00000002, SHIIRESAKI_CD=00000001}
size:4
$


環境:
MacOSX 10.4.2
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_07-215)

Macだと動いてPCだとだめってことではないでしょうから、テストケースをシンプルにしてもう一度検証してはいかがでしょうか。

[ メッセージ編集済み 編集者: インギ 編集日時 2005-07-26 17:28 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-07-26 17:49
もしかして、内部データ構造を見て勘違いしていないでしょうか。

単純に内部構造をデバッガで見たうえで勘違いしていると仮定した場合の話ですが・・・

HashMapは、
・ハッシュ値はキーと値を元に算出されている
・配列のあるインデックスにオブジェクトを格納するが、
  配列のインデックスはハッシュ値から算出した数値を使用する
・衝突した場合はリスト構造にて接続して格納
といったアルゴリズムで作られています。

引用:

[3]= HashMap$Entry (ID=5829)
hash= -329363325
key= "START_YMD"
next= HashMap$Entry (ID=5833)
hash= 1887899603
key= "NONYUSAKI_CD"
next= null
value= "00000002"
value= "1985/10/01"


・"START_YMD"とその値から算出したハッシュ値が-329363325
・"NONYUSAKI_CD"とその値から算出したハッシュ値が1887899603
・それぞれのハッシュ値から求めたインデックスは3
と言う事がわかります。

それぞれのオブジェクトが衝突してしまった為、
HashMap$Entryのnextフィールドを使用して同一のインデックスに
複数のオブジェクトを格納している状態です。

そして"START_YMD"の値を変えた場合、キーと値からハッシュ値を求めている為、
ハッシュ値から求めたインデックスは3以外になったと言う事でしょう。
だからデバッガ上では他の要素へ移動しているのです。

そもそもMapとはインデックスでのアクセスを行う為のものではないので
移動したところで何も問題ありません。
K2
会議室デビュー日: 2002/12/19
投稿数: 7
投稿日時: 2005-07-26 18:27
みなさんありがとうございました。

今回の件ですが、
とあるデータベース接続のフレームワークに
HashMapをパラメータとして渡して、
キーと値でSQLを作成を行うようになっているのですが、
nextの値が完全に無視されていたので、
てっきり要素に重複してセットされているのがまずいのだろうと考えてしまいました。
この件に関しては、開発元に問い合わせてみます。

インギさん
私の環境でも同じように表示されました。
インギさんの方法では確認していませんでしたので、
セットの仕方は問題ないと確認できたので助かりました。
ご確認いただき、ありがとうございました。

かつのりさん
詳しくご説明いただきありがとうございました。
デバッガの値を見て確認していたので、
これが問題だろうと考えていました。
ハッシュの考え方もわかり大変参考になりました。
ありがとうございます。
1

スキルアップ/キャリアアップ(JOB@IT)