603 Stimmen

Wie kann man die Hashmaps verwenden?

Ich habe dieses Feld:

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

Für jede Hash<String, HashMap> Ich muss eine ComboBox , deren Elemente der Wert (der zufällig selbst eine HashMap ist) von HashMap <String, **HashMap**> .

Zur (nicht funktionierenden) Demonstration:

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 Stimmen

In Java 8 mit Lambda : stackoverflow.com/a/25616206/1503859

0 Stimmen

Java 8 mit Streams : stackoverflow.com/a/32343195/1216775 Ein Vorteil von Streams ist, dass sie auch parallelisiert werden können.

1415voto

Cyril N. Punkte 37150

Ich weiß, dass ich damit etwas spät dran bin, aber ich erzähle auch, was ich gemacht habe, falls es jemandem hilft:

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.
}

129 Stimmen

Ich weiß nie mehr, wie ich das schreiben soll, also komme ich immer wieder auf dieselbe Antwort zurück. Upvoted, weil dies saubere Antwort ist und dieser Code an so vielen Stellen in meinen Projekten eingefügt wird, danke!

16 Stimmen

@Katu schreiben Sie einfach Ihremap..entrySet().for und die IDE-Autovervollständigung wird es verarbeiten.

298voto

Nitin Mahesh Punkte 3592

Lambda Ausdrucksweise Java 8

In Java 1.8 (Java 8) ist dies viel einfacher geworden, indem man forEach Methode von Aggregate operations( Stream-Operationen ), die ähnlich aussehen wie die Iteratoren von Iterierbar Schnittstelle.

Kopieren Sie einfach die folgende Anweisung in Ihren Code und benennen Sie die HashMap variabel von hm an Ihre HashMap-Variable, um ein Schlüssel-Wert-Paar auszugeben.

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));

Hier ist ein Beispiel, bei dem ein Lambda-Ausdruck verwendet wird:

    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

Man kann auch verwenden Spliterator für dasselbe.

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

UPDATE


Einschließlich Dokumentationslinks zu Oracle Docs. Für mehr über Lambda Hier geht's weiter Link und muss lesen Aggregierte Operationen und für Spliterator gehen Sie zu diesem Link .

1 Stimmen

Und ich schätze, wir können keine lokalen Variablen innerhalb des umschließenden Bereichs verwenden, ohne sie als endgültig zu deklarieren. Ich habe Local variable schedule defined in an enclosing scope must be final or effectively final bei der Verwendung von Variablen, die außerhalb des Lambda-Körpers deklariert sind, im Gegensatz zu Closures in Groovy.

5 Stimmen

Der Nachteil bei der Verwendung von Lambdas ist, dass Sie die andere Methode nicht zurückgeben können, während Sie sich innerhalb des Lambdas befinden.

0 Stimmen

Wozu dient der Spliterator hier? Verwenden Sie parallele Streams?

55voto

Bert F Punkte 81431

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);
   }
}

2 Stimmen

+1: Dies ist ein besserer Ansatz als meine Antwort (vorausgesetzt, wir verwenden Java 5 oder höher)

1 Stimmen

Die Verwendung von generischen Args auf der äußeren HashMap scheint auf Java 5 oder höher hinzuweisen. [Aber ich habe mich gefragt, welches Java das war, da die innere HashMap keine generischen Args hatte und es einen Array-Zugriff auf eine HashMap gab... aber das ist nur ein "Pseudo"-Code, um die Frage zu übermitteln. ]]

1 Stimmen

Könnten Sie erklären, warum es bei Ihnen nicht funktioniert hat? Verwenden Sie Java 5 oder höher? Wir folgen Ihrem Codebeispiel, das anscheinend nichts mit dem Kombinationsfeld macht, sobald es erstellt ist. Oder sind die Werte nicht in der gewünschten Reihenfolge? Oder brauchten Sie die Schlüssel anstelle der Werte in der Combobox? Ich denke, die meisten würden zustimmen, dass jede der 3 bisherigen Antworten gut funktionieren sollte. Wahrscheinlich gibt es also ein Problem bei der Anwendung der Antwort oder ein anderes Problem an anderer Stelle, bei dem wir vielleicht helfen können, wenn Sie uns mehr Informationen geben.

33voto

akhil_mittal Punkte 20953

Ströme Java 8

Zusammen mit forEach Methode, die eine Lambda-Ausdruck haben wir auch Strom APIs, in Java 8.

Iterieren Sie über Einträge (mit forEach und Streams):

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);
        });

Der Vorteil von Streams ist, dass sie leicht parallelisiert werden können und nützlich sind, wenn wir mehrere CPUs zur Verfügung haben. Wir müssen einfach parallelStream() anstelle von stream() oben. Bei parallelen Strömen ist es sinnvoller, die forEach como forEachOrdered würde keinen Unterschied in der Leistung machen. Wenn wir über Schlüssel iterieren wollen, können wir sample.keySet() und für Werte sample.values() .

Warum forEachOrdered et non forEach mit Strömen ?

Ströme bieten auch forEach Methode, aber das Verhalten von forEach explizit nicht-deterministisch ist, während die forEachOrdered führt für jedes Element dieses Streams eine Aktion durch, und zwar in der Begegnungsreihenfolge des Stroms wenn der Stream eine bestimmte Reihenfolge der Begegnungen hat. Also forEach garantiert nicht, dass der Auftrag eingehalten wird. Auch prüfen este für mehr.

23voto

Oliver Charlesworth Punkte 259497

Sie können eine Iteration über eine HashMap (und viele andere Sammlungen) mit Hilfe eines Iterators, z.B.:

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

...

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

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

2 Stimmen

Ich kann mich mit einem solchen Entwurf nicht auf die Ebene darunter herablassen

3 Stimmen

@Ja, das können Sie. Sie können einen inneren Iterator erstellen, der auf it.next() .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X