• ベストアンサー

List と Mapの機能を持つ方法

・欲しい機能 複数の同じ型のクラスを格納して、キーまたは登録順で呼び出したい。 イメージとしては、 arraylist.get(index) hashmap.get(key) を持つ機能です。 この2つの機能を持つ、クラスは、無いでしょうか? ListやMapにこだわりません。 無い場合、自作する必要があるのですが、 参考になる、HPや本などをご存知の型は、教えていただきたいのですが… 作成経験のある方の、アドバイスなどもいただけると嬉しいです。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • deadlock
  • ベストアンサー率67% (59/87)
回答No.3

順序の保証は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フィールドへの移譲メソッドをゴリゴリ書く }

namida6000
質問者

補足

LinkedHashMapが直系のサブクラスにあったんですね… 勉強不足でした。 自作する場合の対応方法まで記述していただき、感謝しております。 ただ、説明いただいた、下記の部分について、理解できていません。 > Map への変更が終わってから参照 > 更新・参照が混じっているときは工夫が要ります。 私の理解不足の箇所 変更が終わると言うのは、どのタイミングになりますか? put()しただけでは、変更は終了しないのでしょうか? ---------------------------------------------------------------- 私のプログラムの処理概要 map(データのmap) 1.データをmapへ収集する 所得した複数のデータをmapへ追加(put)する。 (追加した順番は、データの分析や表示で重要) 2.データを分析する キーを使って、map内のデータを比較や計算 必要に応じて、map内のデータを修正 表示内容を決定 3.データ一覧を表示 一覧を出したり、mapのキーやlistの番号で表示する。 1.と2.は、一つのメソッド内で処理が行われます。 3.は、paintメソッドで処理が行われます。 この場合は、更新と参照が混じっているという定義に当てはまりますか? ---------------------------------------------------------------- 詳しく教えていただいたのに、新たに質問をして、申し訳ございません。 大変恐縮ですが、この部分について、もう少し教えていただけないでしょうか? よろしくお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • deadlock
  • ベストアンサー率67% (59/87)
回答No.5

> 変更が終わると言うのは、どのタイミングになりますか? > 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と、前述のキーの変更が混じっているかどうかです。

namida6000
質問者

お礼

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)
回答No.4

一個書き忘れました。 もし要件が書き込んだ順に取り出したいというだけなら、 Iterator iter = linkedHashMap.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); Object value = linkedHashMap.get(key); // 何か処理 } だけでいいです。ArrayListに移したり、クラスを作ったりはいりません。

全文を見る
すると、全ての回答が全文表示されます。
noname#49664
noname#49664
回答No.2

要するに、並び順の保障されたHashTableがほしい、ということでしょうか。 1つのクラスで実現するのにこだわるのであれば別ですが、例えばHashMapにキーと値を保管し、そのキーをArrayListで管理する、というのではまずいんでしょうか。

namida6000
質問者

お礼

返信が遅れ申し訳ございません。 > 要するに、並び順の保障されたHashTableがほしい、ということでしょうか。 はい。 > 1つのクラスで実現するのにこだわるのであれば別ですが、 > 例えばHashMapにキーと値を保管し、そのキーをArrayListで管理する、というのではまずいんでしょうか。 出来れば、既存のクラスの利用を、 無い場合も、いくつかの箇所で利用する事を想定している為、一つのクラスにしたいと思っています。 ただ、作成したクラスは、listやmapなどjavaのネイティブなIFで利用する事を希望しています。 両方の機能をもつクラスという事で、単純にListとMapをimplementsして、 ブリッジパターンで対応しようと考えましたが、 removeメソッドで重複してしまいます。 困っていたところ、 deadlockさんに、LinkedHashMapに教えていただきました。 こちらを調査してみようと思います。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1
namida6000
質問者

お礼

下のアドレスは、私の環境から見る事が出来ませんでした。 http://www006.upp.so-net.ne.jp/ugougo/blogger/2/2006/06/javamapput.html もう一つのほうですが、ピュアjavaのAPI以外利用できません。 私の説明が不足しておりました。 せっかく探していただいたのに申し訳ございません。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ArrayList内HashMapの取得

    基本的で申し訳ないのですが一番下の行で リストの3つめの要素内のkey=key2でyeahをコンソールに出力したいです。 どのように取得すればいいのでしょうか? list.get(2).get("key2")っぽいかんじで... ArrayList list = new ArrayList(); for (int i = 0; i < 5; i++) { HashMap map = new HashMap(); map.put("key1", "hello"); map.put("key2", "yeah"); map.put("key3", "boo"); list.add(map); } System.out.println(list.get(2));

    • ベストアンサー
    • Java
  • LISTとMAPについて

    以下のように記述されたコードで 他クラスからこのクラスのインスタンスを生成して tempMapのkeyとValueを抜き出したいのですが なにか良い方法ありますでしょうか? 宜しくお願いします。 public class TestListMap { protected List list = null; private Map tempMap = null; public TestListMap(){ list = new ArrayList(); for(int i=0; i < 10; i++ ){ tempMap = new HashMap(); tempMap.put("NO", "00" + i); tempMap.put("TYPE", "AAA" + i); if (i % 2 == 0 | i % 3 == 0) { tempMap.put("FLG", "1"); } else { tempMap.put("FLG", "0"); } list.add(tempMap); } } public List getListMap(){ return list; } }

    • ベストアンサー
    • Java
  • 2つのリストのマージ方法について

    2つのリストのマージ方法について 下記の要件を満たしたいと考えています。 ・リスト1・2をkeyをキーにマージしたい。  リスト1[0]:key=2, value1=b  リスト1[1]:key=3, value1=d  リスト1[2]:key=4, value1=e  ・  ・  ・  リスト2[0]:key=1, value2=A  リスト2[1]:key=2, value2=B  リスト2[2]:key=5, value2=F  リスト2[3]:key=6, value2=G  ・  ・  ・  ↓  リスト3[0]:key=1, value1=A, value=""  リスト3[1]:key=2, value1=b, value=B  リスト3[2]:key=3, value1=d, value=""  リスト3[3]:key=4, value1=e, value=""  リスト3[4]:key=5, value1="", value=F  リスト3[5]:key=6, value1="", value=G  ・  ・  ・ ・リスト1・2はkeyの昇順でソート済。各リスト内では重複しているkeyはない。 ・マージ後もkeyの昇順にしたい。 ・実際のリストはそれぞれ数万件~数十万件なので、パフォーマンスを考慮したい。 下記のように作成してみたのですが、無理やりやりました感があり、分かりづらくバグがありそうです。またループでnewもしてたりしてパフォーマンスも悪そうです。もっとスマートにパフォーマンスもよい方法がないでしょうか? int checkedCount = 0; for (int i = 0; i < list1.size(); i++) { String str1 = list1.get(i).get("key"); for (int j = checkedCount; j < list2.size(); j++) { Map<String, String> map3 = new HashMap<String, String>(); String str2 = list2.get(j).get("key"); if (str1.compareTo(str2) < 0) { if (i != list1.size() - 1) { map3.put("key", str1); map3.put("value1", list1.get(i).get("value1")); map3.put("value2", ""); list3.add(map3); break; } else { Map<String, String> map4 = new HashMap<String, String>(); map4.put("key", str2); map4.put("value1", ""); map4.put("value2", list2.get(j).get("value2")); list3.add(map4); } } else if (str1.compareTo(str2) == 0) { map3.put("key", str1); map3.put("value1", list1.get(i).get("value1")); map3.put("value2", list2.get(j).get("value2")); list3.add(map3); checkedCount = j + 1; break; } else { map3.put("key", str2); map3.put("value1", ""); map3.put("value2", list2.get(j).get("value2")); list3.add(map3); checkedCount = j + 1; } } }

    • ベストアンサー
    • Java
  • MAPの配列・・・???!!!

    Mapというものを使うのが初めてなのですが、 よくわからなくなってしまいました。 他のプログラムから、 「MAPの配列で返ってくる」 のですが、このMAPの配列をintひとつ、ストリング2つから 作ろうとしているのですが、できずに困っています。 map[0]=("abc","ABC") map[1]=("def","DEF") map[2]=("ghi","GHI") ・ ・ みたいなイメージなのですが、エラーになります・・・ Map[] hairetu = new HashMap(); これでコンパイルできません。 HelloWorldMap.java:17: 互換性のない型 出現: java.util.HashMap 要求: java.util.Map[] Map[] hairetu = new HashMap(); Map[] hairetu; という宣言だけならできます。 受け渡し先でMapの配列を要求しているのでこのような形が必要なのですが・・・ ちなみにソースを見ると hairetu[i].get(キー) みたいなとり方をしています。

    • ベストアンサー
    • Java
  • MAPに関して

    以下のように、マップにCLASS_Aのリストのリストを格納しています。 CLASS_A { private int a getter setter } MAP<String,List<List<CLASS_A>>> map = new HashMap<String,List<List<classA>>> キーを元に、マップからリストのリストを取得した場合に CLASS_Aからint aを取得する場合 for List<List<CLASS_A> a : DaoList(Daoの取得結果)) for List<CLASS_A> b : a) b.get() } } でよろしいでしょうか? (2重ループになってしまうので、もっと簡単な取得方法あったら教えてください)

  • hashCodeの使用について

    いつもお世話になっています。 hashCodeについて聞きたいのですが、 hashCodeは、暗号化にも利用されるらしいのですが、 使用理由がよくわかりません。 その場合、 http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000045.htmlのURLによると、 HashMapクラスはキーからハッシュコードを取得し、ハッシュコードごとにグループ分けして値を格納する。 値を取得する時には、取り出すために渡されたキーからハッシュコードを取得し、そのハッシュコードを元にまず ハッシュコードごとのグループを取得し、 その後グループ内でキーを元に全検索を行う。 この方法によりHashMapクラスは値の検索がArrayListクラスよりも 早い。 また、ハッシュコードから元のデータは復元できないため、暗号化にも 使用される。 、 どういうことなのでしょうか? 上記の文を解釈して、ソースを作成しようとは思ったのですが、 よくわかりません。 作成してみたソースは、 HashMap hashMap = new HashMap(); //ハッシュコードで格納するmapデータ Map map = new HashMap(); map.put(0,"Tell"); map.put(1, "AAA"); map.put(2,"TTT"); //ハッシュコード String keyword = "keyword"; int key = keyword.hashCode(); //ハッシュコードでキーを設定 hashMap.put(key,map); //格納するMap Map maP = new HashMap(); for(int h=0;h<hashMap.size();h++) { //キーワードをハッシュコードに変換 int stK =keyword.hashCode(); //ハッシュコードで格納したMapデータの取り出し maP = (Map) hashMap.get(stK); } //Mapデータ表示 for(int i=0;i<maP.size();i++) { System.out.println(maP.get(i)); } つまり、ハッシュコードは文字が暗号化され、元の文字がわからない = 暗号化されたに等しくなる ということだけは何とかわかるような気はするのですが。。。 聞きたいのは、ハッシュコードをmapキーにした場合、 後でもし取り出したくなったりしたらどうすべきなのでしょうか? たとえば、どういった処理の場合に使用できるのでしょうか? また、hashCode()はしょっちゅう使用すべきではないのでしょうか? 宜しくお願いします。

    • ベストアンサー
    • Java
  • Javaを勉強しています。

    現在、Javaの勉強中なので初歩的な質問ですみません。 #色々な本やググってみたのですが、未だ理解できないでいます。 Javaでは、たとえば(1)のように左辺(List)の型と右辺(ArrayList)の型が 違う場合でも問題なく使用できるようです。 (1)と(2)で何の違いがあるのか理解できておりません。 何が違うのでしょうか。 (1)List<Integer> i = new ArrayList<Integer>(); (2)ArrayList<Integer> i = new ArrayList<Integer>(); その類件としては以下があります。。 (3)Map y = new HashMap(); (4)HashMap y = new HashMap(); ご教授いただけますと幸いです。 宜しくお願いいたします。

  • Map<T, ArrayList<T>>にput

    Map<String, ArrayList<Long>> map = new HashMap<String, ArrayList<Long>>(); と宣言された map に put()する方法を教えて下さい。言語はJavaです。 mapの値がArrayListのため、map.put("key", 10L);のように直接代入することができません。 解決策を教えて下さい。 ※質問のタイトルは字数制限のため、変なタイトルになっています。

    • ベストアンサー
    • Java
  • HashMap要素の操作について

    過去質問を検索致しましたが、適当な質問を見つけられなかった為、質問をさせて頂きます。 ●下記コードのうち、AブロックとBブロックとでどのように異なる為、 Aブロックの値操作が、そのままHashMapへ反省されてしまうのかをご教示願えませんでしょうか? コメント"Aブロック"部分でのArrayList型変数へ操作した内容は、そのままHashMap内の当該キー要素に反映されてしまいます。 コメント"Bブロック"で行う、String型への操作は、HashMap内の当該キー要素に反映はされません。 ■実行環境 ・jdk1.3.1_11 ・Windows XP pro SP2 _________________________________________________ HashMap testMap = new HashMap(); // マップへArrayListとStringを追加 testMap.put("KEY_LIST", new ArrayList()); testMap.put("KEY_STRING", "stringVal"); // Aブロック ArrayList testList = (ArrayList) testMap.get("KEY_LIST"); testList.add("one"); testList.add("two"); testList.remove(0); // Bブロック String testString = (String) testMap.get("KEY_STRING"); testString = "one"; testString = ""; _________________________________________________

    • ベストアンサー
    • Java
  • 例えば、以下のようなクラスでmap変数に、あらかじめ値を入れておいて、

    例えば、以下のようなクラスでmap変数に、あらかじめ値を入れておいて、別のクラスで使うときに Common.map.get(""); と書いて、いつでも値を取り出したいのですが、static変数は、コンストラクタでいじれないようで出来ません。 このCommonクラス内であらかじめ値を入れておく方法はあるでしょうか? public class Common{ public static HashMap<String, String> map = new HashMap(); }

    • ベストアンサー
    • Java