- - PR -
ハッシュテーブルについて
1
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-04-04 02:59
自作のhashtblクラス内のhash()メッソドに渡される引数に応じて戻り知が異なることを
期待してコンパイルし実行してみたのですが結果は [{NAIYO=どらえもん, NO=1}, {NAIYO=どらえもん, NO=1}, {NAIYO=どらえもん, NO=1} ,{NAIYO=どらえもん, NO=1}] という結果でした。 期待していた結果としては [{NAIYO=どらえもん, NO=1}, {NAIYO=doraemon, NO=2}, {NAIYO=星陵高校, NO=3} ,{NAIYO=ガリクソン, NO=6}] だったのですがなぜこのような結果になるのでしょうか? hashtblクラス内の String key = (String)e.nextElement(); がうまく機能していないのでしょうか? (hash.java) import java.util.*; public class hash { public static void main(String args[]) { hashtbl has = new hashtbl(); Vector vec; vec = has.hash(2); } (hashtbl.java) import java.util.*; public class hashtbl { public Vector hash(int k) { Vector vec1 = new Vector(); Vector vec2 = new Vector(); Hashtable has1 = new Hashtable(); Hashtable has2 = new Hashtable(); has1.put("1","どらえもん"); has1.put("2","doraemonn"); has1.put("3","星陵高校"); has1.put("4","ゴンザレス"); has1.put("5","カレー"); has1.put("6","ガリクソン"); Enumeration e = has1.keys(); while(e.hasMoreElements()) { String key = (String)e.nextElement(); String value = (String)has1.get(key); has2.put("NO",key); has2.put("NAIYO",value); if(key.equals("4") || key.equals("5")){ vec1.addElement(has2); }else{ vec2.addElement(has2); } } if(k==1){ return vec1; }else{ return vec2; } } } | ||||||||||||
|
投稿日時: 2004-04-04 10:53
何をやりたいのか分からないので、はずしているかもしれませんが。
以下のようにしたらどうでしょうか?
e.nextElement() では 6, 5, 4 ... 1 の順に key が渡されているのでしょう。 最終的に返す Vector にはいつも同じ Hashtable インスタンスを追加しているので、結果として最後に返ったどらえもんで全ての要素が置き換わっってしまいます。 毎回 Hashtable をインスタンス化してやれば、別々に格納されると思います。 | ||||||||||||
|
投稿日時: 2004-04-04 12:16
| ||||||||||||
|
投稿日時: 2004-04-11 14:47
先週、私の質問に対して上記のような御回答を頂きました。御回答の通り試してみたところ 私の期待通りにうまくいきました。 前回とほぼ同様、ハッシューテーブルオブジェクトに格納したkeyとvalueを 表示するサンプルを作成し実行した結果、疑問が浮上しましたので質問させていただきます。
この結果は、{6=ガリクソン, 5=カレー, 4=ゴンザレス, 3=星陵高校, 2=doraemonn, 1=どらえもん}でした。 前回の質問ではwhileループの外でインスタンス化したためHashtableオブジェクトの中身が ループの最終結果に置き換るということでしたがこのことを踏まえると上記の結果は 不思議に思います。、私の予想では{1=どらえもん}という結果しか帰ってこないと思って いました。よろしくお願いいたします。 | ||||||||||||
|
投稿日時: 2004-04-11 17:17
unibon です。こんにちわ。
なにが分からないのかは分かったつもりです。 インスタンス化とループの内・外というのは直接の関係はないです。たまたまそうだからです。 a.add(b) や a.put(b, c) において、 put や add の引数となる b や c と、 put や add の操作の対象となる a との違いです。 b や c は add や put が終わっても、 a の管理の外で依然として内容を変化させることができます。 #うまく説明できません。 まだ先は長いので、できればデバッガを使われて1行ずつステップ実行されて変数をウォッチされるほうが手っ取り早いと思います。ただ、Hashtable はデバッガでも中の値が見づらいので、最初はもっと手軽な配列等で試されたほうが良いかもしれません。 もし、デバッガを使われないとすれば、随所に System.out.println を埋め込んで、行の前後での値の変化を見られたほうが良いでしょう。 | ||||||||||||
|
投稿日時: 2004-04-11 21:26
ループの外で has2 をインスタンス化するということは、このプログラム内で has1 以外の Hashtable オブジェクトは一つしか無いという事です。
かんたろうさんのコードでは Hashtable のインスタンスである has2 に対し、キーの値を固定して(NO と NAIYO)追加していますよね。 has2 に put する度に内容が追加される訳ではなく、置き換えられている訳です。 以下はループ内での has2 の状態です。
上記のように、どのタイミングでも has2 が持つ要素は NO と NAIYO に対応した二つしかありません。 has2 を 格納する Vector のインスタンスである vec2 は、全ての要素がただ一つの has2 への参照なので、最後に置き換えられた「どらえもん」がずらりと並ぶことになるのです。 対して、ループの内で has2 をインスタンス化する場合は、今回の例では has2 に対して 6 つの インスタンスが生成されます。 別々に生成して vec2 に追加する訳ですから、上記のような置き換えが発生しないので個々の値を持ち続けられるのです。 かんたろうさんが改めて質問したコードでは Hashtable に追加する際に、キーの値を毎回変えて追加していますので、全て別々の要素として(置き換えられる事無く)存在できるのです。 | ||||||||||||
|
投稿日時: 2004-04-11 22:27
余計なお世話かもしれませんが、has2 としての Hashtable の使い方がいまいちズレているように感じます。
最終的に欲しい内容がプルダウンにしたい内容の一覧であるならば、値を保持するクラスを作って、それを Vector に追加するのがいいのではないでしょうか? 例えば、こんなクラスを作って
こうしてみるとか
ただ、この場合もループの外で ValueObject をインスタンス化すると、全ての要素が「どらえもん」で汚染されます。 以下、駄目な例です。
この例で、発生していた現象が理解し易くなるのではないかと思います。 | ||||||||||||
|
投稿日時: 2004-04-12 00:40
なるほど!!ハッシュテーブルのオブジェクトの中身が置き換えられるか置き換えられない
かはキーが左右していたのですね。あと、サンプルを書いてくださいましてありがとうござい ます。大変参考になりました。今後活用させていただきたいと思います。 お答えくださいましたunibonさん、でゅうくさん本当にありがとうございました。 | ||||||||||||
1
