- ベストアンサー
List と Mapの機能を持つ方法
・欲しい機能 複数の同じ型のクラスを格納して、キーまたは登録順で呼び出したい。 イメージとしては、 arraylist.get(index) hashmap.get(key) を持つ機能です。 この2つの機能を持つ、クラスは、無いでしょうか? ListやMapにこだわりません。 無い場合、自作する必要があるのですが、 参考になる、HPや本などをご存知の型は、教えていただきたいのですが… 作成経験のある方の、アドバイスなどもいただけると嬉しいです。 よろしくお願いいたします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
順序の保証はLinkedHashMapでできます。 このクラスは内部にLinkedListを持ち、キーの追加順序を保持しています。 indexで使うときは、 List keyList = new ArrayList(linkedHashMap.keySet()); Map への変更が終わってから参照するのであれば、上記で十分だと思います。 もしクラスにするならこんな感じでしょうか。 更新・参照が混じっているときは工夫が要ります。 コンパイル確認していないので、メソッド名とか間違っていたら適当に直してください。 public class IndexedMap implements Map { private Map map = new LinkedHashMap(); private List keyList; // 更新終了用。 public boolean fix() { // index問い合わせに使うリストを取得。index問い合わせはArrayListが速い this.list = new ArrayList(map.keySet()); // Mapを変更不可にする。 this.map = Collections.unmodifiableMap(this.map); } // index問い合わせ用 public Ojbect get(int index) { if (this.keyList == null) { // 何か例外を投げる } return this.map.get(this.keyList.get(index)); } public Object put(Object key, Object value) { this.map.put(key, value); } // 上のputのように、mapフィールドへの移譲メソッドをゴリゴリ書く }
その他の回答 (4)
- deadlock
- ベストアンサー率67% (59/87)
> 変更が終わると言うのは、どのタイミングになりますか? > put()しただけでは、変更は終了しないのでしょうか? removeや、新しいキーのputがなくなるタイミングということです。 サンプルコードのようにキーを移し替えたArrayListには、元のMapのキー追加/削除が反映されないという点です。 linkedHashMap.put("A", avalue); linkedHashMap.put("B", bvalue); List keyList = new ArrayList(linkedHashMap.keySet()); linkedHashMap.put("C", cvalue); linkedHashMap.remove("A"); のコードでは、keyListに対して"C"の追加も、"A"の削除も反映されません。 プログラムの概要で行くと、 > 2.データを分析する の段階で、indexでのgetと、前述のキーの変更が混じっているかどうかです。
お礼
deadlockさま 当初の質問以外の事まで、ご説明していただき、大変恐縮しております。 > linkedHashMap.put("A", avalue); > linkedHashMap.put("B", bvalue); > List keyList = new ArrayList(linkedHashMap.keySet()); > linkedHashMap.put("C", cvalue); > linkedHashMap.remove("A"); > のコードでは、keyListに対して"C"の追加も、"A"の削除も反映されません。 サンプルコードを見て、よく理解できました。 ありがとうございました。
- deadlock
- ベストアンサー率67% (59/87)
一個書き忘れました。 もし要件が書き込んだ順に取り出したいというだけなら、 Iterator iter = linkedHashMap.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); Object value = linkedHashMap.get(key); // 何か処理 } だけでいいです。ArrayListに移したり、クラスを作ったりはいりません。
要するに、並び順の保障されたHashTableがほしい、ということでしょうか。 1つのクラスで実現するのにこだわるのであれば別ですが、例えばHashMapにキーと値を保管し、そのキーをArrayListで管理する、というのではまずいんでしょうか。
お礼
返信が遅れ申し訳ございません。 > 要するに、並び順の保障されたHashTableがほしい、ということでしょうか。 はい。 > 1つのクラスで実現するのにこだわるのであれば別ですが、 > 例えばHashMapにキーと値を保管し、そのキーをArrayListで管理する、というのではまずいんでしょうか。 出来れば、既存のクラスの利用を、 無い場合も、いくつかの箇所で利用する事を想定している為、一つのクラスにしたいと思っています。 ただ、作成したクラスは、listやmapなどjavaのネイティブなIFで利用する事を希望しています。 両方の機能をもつクラスという事で、単純にListとMapをimplementsして、 ブリッジパターンで対応しようと考えましたが、 removeメソッドで重複してしまいます。 困っていたところ、 deadlockさんに、LinkedHashMapに教えていただきました。 こちらを調査してみようと思います。 ありがとうございました。
- himajin100000
- ベストアンサー率54% (1660/3060)
何かそれっぽいこと言っているような気がするけど使ってみてないのでよくわからん。 http://www006.upp.so-net.ne.jp/ugougo/blogger/2/2006/06/javamapput.html http://commons.apache.org/collections/apidocs-COLLECTIONS_3_1/org/apache/commons/collections/map/ListOrderedMap.html
お礼
下のアドレスは、私の環境から見る事が出来ませんでした。 http://www006.upp.so-net.ne.jp/ugougo/blogger/2/2006/06/javamapput.html もう一つのほうですが、ピュアjavaのAPI以外利用できません。 私の説明が不足しておりました。 せっかく探していただいたのに申し訳ございません。
補足
LinkedHashMapが直系のサブクラスにあったんですね… 勉強不足でした。 自作する場合の対応方法まで記述していただき、感謝しております。 ただ、説明いただいた、下記の部分について、理解できていません。 > Map への変更が終わってから参照 > 更新・参照が混じっているときは工夫が要ります。 私の理解不足の箇所 変更が終わると言うのは、どのタイミングになりますか? put()しただけでは、変更は終了しないのでしょうか? ---------------------------------------------------------------- 私のプログラムの処理概要 map(データのmap) 1.データをmapへ収集する 所得した複数のデータをmapへ追加(put)する。 (追加した順番は、データの分析や表示で重要) 2.データを分析する キーを使って、map内のデータを比較や計算 必要に応じて、map内のデータを修正 表示内容を決定 3.データ一覧を表示 一覧を出したり、mapのキーやlistの番号で表示する。 1.と2.は、一つのメソッド内で処理が行われます。 3.は、paintメソッドで処理が行われます。 この場合は、更新と参照が混じっているという定義に当てはまりますか? ---------------------------------------------------------------- 詳しく教えていただいたのに、新たに質問をして、申し訳ございません。 大変恐縮ですが、この部分について、もう少し教えていただけないでしょうか? よろしくお願いいたします。