2010-11-20 4 views
347

どのようにハッシュマップごとに?

私はこのフィールドを持っています:

HashMap<String, HashMap> selects = new HashMap<String, HashMap>(); 

Hash<String, HashMap>に対して、ComboBoxの値を(そのHashMap自体である)HashMap <String, **HashMap**>にする必要があります。

(機能しない)デモンストレーションの手段として:

for (int i=0; i < selects.size(); i++) { 
    HashMap h = selects[i].getValue(); 
    ComboBox cb = new ComboBox(); 

    for (int y=0; y < h.size(); i++) { 
     cb.items.add(h[y].getValue); 
    } 
} 
+3

ラムダを使用しているJava 8:http://stackoverflow.com/a/25616206/1503859 –

答えて

856

私はその1のビット遅刻を知っているが、私は私があまりにもやったことを共有しましょう、私は、一般的にcx42netと同じことを行う

HashMap<String, HashMap> selects = new HashMap<String, HashMap>(); 

for(Map.Entry<String, HashMap> entry : selects.entrySet()) { 
    String key = entry.getKey(); 
    HashMap value = entry.getValue(); 

    // do what you have to do here 
    // In your case, another loop. 
} 
+40

私はこれを書く方法を覚えていないので、私はいつも同じ答えに戻ってきます。 Upvoted、これはきれいな答えであり、このコードは私のプロジェクトの多くの場所に貼り付けられたコピーですので、ありがとう! – Katu

+1

@ Katuはyourmap..entrySet()。forを書くだけで、IDEオートコンプリートがそれを処理します。 –

2

使用entrySet、ここでは例を参照してください。

+0

icyrock.com、do not work – Mediator

+1

これは確かに動作し、私は毎日使っています。あなたは 'HashMap 'を持っているので、外側と内側HashMapの2つのループが必要です。 Btw - 2番目のHashMapを確実に入力する必要があります.HashMap >のようなものですが、あなたの例では、HashMap > '。もう一つのことは、できればインターフェイス 'Map 'を使用することです。 –

43

Map.values()

HashMap<String, HashMap<SomeInnerKeyType, String>> selects = 
    new HashMap<String, HashMap<SomeInnerKeyType, String>>(); 

... 

for(HashMap<SomeInnerKeyType, String> h : selects.values()) 
{ 
    ComboBox cb = new ComboBox(); 
    for(String s : h.values()) 
    { 
     cb.items.add(s); 
    } 
} 
あなたが例えば、イテレータを使用して HashMap(および他の多くのコレクション)を反復処理することができます
+1

+1:これは私の答え(Java 5以降を使用していると仮定)よりも控えめなアプローチです –

+0

外側のHashMapにジェネリックargsを使用すると、Java 5以降を示すように見えます。 [[しかし、内部HashMapにはジェネリック引数がなく、HashMapで配列アクセスが行われていたので、Javaが何だったのか不思議でした...しかし、質問を伝えるためのちょっとした "疑似"コードです。 ]] –

+0

バートFさん、仕事をしないでください – Mediator

13

HashMap<T,U> map = new HashMap<T,U>(); 

... 

Iterator it = map.values().iterator(); 

while (it.hasNext()) { 
    System.out.println(it.next()); 
} 
+1

私はそのようなデザインでレベル以下まで – Mediator

+2

まではできません。 'it.next()'に基づいて内部イテレータを作成することができます。 –

12

が、私は明示的にエントリを作成しない:場合、それは他の誰かに役立ちます。

HashMap<String, HashMap> selects = new HashMap<String, HashMap>(); 
for (String key : selects.keySet()) 
{ 
    HashMap<innerKey, String> boxHolder = selects.get(key); 
    ComboBox cb = new ComboBox(); 
    for (InnerKey innerKey : boxHolder.keySet()) 
    { 
     cb.items.add(boxHolder.get(innerKey)); 
    } 
} 

これはちょうど私の最も直感的なようだ、私はマップの値を反復に対する偏見だと思います。

153

ラムダ式のJava 1.8(Javaの8)でJava 8

が、これはイテレータのようになります集約操作(ストリーム操作)からのforEachメソッドを使用して、ずっと簡単になってきましたIterableインターフェイスから。

はちょうどあなたのコードに文の下にペーストをコピーして、キーと値のペアをプリントアウトしてお使いのHashMapの変数にHMからHashMapの変数の名前を変更します。ここ

HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>(); 
/* 
*  Logic to put the Key,Value pair in your HashMap hm 
*/ 

// Print the key value pair in one line. 
hm.forEach((k,v) -> System.out.println("key: "+k+" value:"+v)); 

ラムダ式を用いた例である。

HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>(); 
    Random rand = new Random(47); 
    int i=0; 
    while(i<5){ 
     i++; 
     int key = rand.nextInt(20); 
     int value = rand.nextInt(50); 
     System.out.println("Inserting key: "+key+" Value: "+value); 
     Integer imap =hm.put(key,value); 
     if(imap == null){ 
      System.out.println("Inserted"); 
     } 
     else{ 
      System.out.println("Replaced with "+imap); 
     }    
    } 

    hm.forEach((k,v) -> System.out.println("key: "+k+" value:"+v)); 

Output: 

Inserting key: 18 Value: 5 
Inserted 
Inserting key: 13 Value: 11 
Inserted 
Inserting key: 1 Value: 29 
Inserted 
Inserting key: 8 Value: 0 
Inserted 
Inserting key: 2 Value: 7 
Inserted 
key: 1 value:29 
key: 18 value:5 
key: 2 value:7 
key: 8 value:0 
key: 13 value:11 

また一つが同じためSpliteratorを使用することができます。Oracleのドキュメントへのドキュメントリンクを含む

Spliterator sit = hm.entrySet().spliterator(); 

UPDATE


。 詳細についてラムダこれに行くlinkそしてAggregate Operationsを読む必要があり、Spliteratorのためにこれはlinkに行く。

+0

と私は、最終的に宣言することなく、囲みスコープ内のローカル変数を推測することはできないと思います。 groovyのクロージャとは異なり、ラムダボディの外側で宣言された変数を使用しているときに、 '囲みスコープで定義されたローカル変数スケジュールは最終的にまたは効果的にfinal'でなければなりません。 – Mahesha999

+2

ラムダを使用することの欠点は、ラムダ内では、他の方法を返すことができないことです。 – apscience

5

既に言及したように、Java 8ではlambda expressionを受け入れるforEachメソッドがあります。しかし、我々はstream APIも持っています。 (forEachのとストリームを使用して)エントリを超える

反復:

sample.forEach((k,v) -> System.out.println(k + "=" + v)); 
sample.entrySet().stream().forEachOrdered((entry) -> { 
      Object currentKey = entry.getKey(); 
      Object currentValue = entry.getValue(); 
      System.out.println(currentKey + "=" + currentValue); 
     }); 
sample.entrySet().parallelStream().forEach((entry) -> { 
      Object currentKey = entry.getKey(); 
      Object currentValue = entry.getValue(); 
      System.out.println(currentKey + "=" + currentValue); 
     }); 

ストリームの利点は、彼らが簡単に並列化することができ、私たちは自由に複数のCPUを持っていたときに役立つことができます。上記のstream()の代わりにparallelStream()を使用するだけです。パラレルストリームでは、forEachforEachOrderedとして使用する方がパフォーマンス上の違いはありません。キーを反復処理する場合は、sample.keySet()と値sample.values()を使用できます。

なぜforEachOrderedで、ストリームではないforEach

ストリームはまた、forEach方法を提供するが、forEachの挙動は、ストリームが定義された出会いの順序を有する場合forEachOrderedストリームの遭遇ために、このストリームの各要素のためのアクションを実行する場合のように明示的に非決定的です。したがって、forEachは注文が保たれることを保証しません。詳細についてはthisもチェックしてください。

+0

複数の質問に同じ回答を投稿しないでください。 1つの良い答えを投稿し、投票/フラグを立てて他の質問を重複として閉じます。質問が重複でない場合は、*あなたの質問に対する回答を調整してください。* – durron597

+0

それに応じて回答が更新されました。 –