Cum să pentru fiecare hashmap? [duplicat] (Programare, Java)

Mediator a intrebat.

Am acest câmp:

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

Pentru fiecare Hash<String, HashMap> Am nevoie să creez un ComboBox, ale cărui elemente sunt valoarea (care se întâmplă să fie ea însăși un HashMap) a lui HashMap <String, **HashMap**>.

Cu titlu de demonstrație (nefuncțională):

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

Comentarii

  • În Java 8 folosind Lambda : stackoverflow.com/a/25616206/1503859 –  > Por Nitin Mahesh.
  • Java 8 folosind fluxuri : stackoverflow.com/a/32343195/1216775 , un avantaj al fluxurilor este că pot fi și ele paralelizate. –  > Por akhil_mittal.
7 răspunsuri
Cyril N.

Știu că am întârziat un pic pentru asta, dar voi împărtăși și eu ce am făcut, în caz că ajută pe altcineva :

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

Comentarii

    115

  • Nu-mi amintesc niciodată cum să scriu asta, așa că mă întorc mereu la același răspuns. Upvoted, pentru că acesta este un răspuns curat și acest cod este copiat și lipit în atât de multe locuri în proiectele mele, mulțumesc! –  > Por Katu.
  • @Katu scrie doar yourmap..entrySet().for și autocompletarea IDE se va ocupa de asta. –  > Por AITAALI_ABDERRAHMANE.
Nitin Mahesh

Lambda Expresie Java 8

În Java 1.8 (Java 8) acest lucru a devenit mult mai ușor prin utilizarea forEach din operațiunile agregate(Operațiuni de flux), care seamănă cu iteratorii din Iterable Interfață.

Trebuie doar să copiați și să lipiți declarația de mai jos în codul dvs. și să redenumiți metoda HashMap din hm în variabila HashMap pentru a tipări perechea cheie-valoare.

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

Iată un exemplu în care un expresie Lambda este utilizată:

    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

De asemenea, se poate utiliza Spliterator pentru același lucru.

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

UPDATE


Inclusiv linkurile de documentare către Oracle Docs.Pentru mai multe informații despre Lambda mergeți la acest link link și trebuie să citiți Operațiuni agregate iar pentru Spliterator, accesați acest link link.

Comentarii

  • și presupun că nu putem avea variabile locale în interiorul domeniului de cuprindere fără să le declarăm finale. Am găsit Local variable schedule defined in an enclosing scope must be final or effectively final în timp ce se utilizează o variabilă declarată în afara corpului lambda, spre deosebire de închiderile din groovy. –  > Por Mahesha999.
  • Dezavantajul utilizării lambdas este că nu puteți returna cealaltă metodă, în timp ce vă aflați în interiorul lambda. –  > Por apscience.
  • Care este utilizarea spliteratorului aici? Folosiți fluxuri paralele? –  > Por akhil_mittal.
Bert F

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

Comentarii

  • +1: Aceasta este o abordare mai curată decât răspunsul meu (presupunând că folosim Java 5 sau o versiune ulterioară) –  > Por Oliver Charlesworth.
  • Utilizarea de argumente generice pe HashMap exterior pare să indice Java 5 sau o versiune ulterioară. [[ Dar m-am întrebat despre ce Java era vorba, deoarece HashMap-ul interior nu avea arge generice și se făcea o accesare a unui array pe un HashMap… dar este doar un „pseudocod” pentru a transmite întrebarea. ]] –  > Por Bert F.
  • Vrei să explici de ce nu pare să funcționeze pentru tine? Folosiți Java 5 sau o versiune ulterioară? Urmăm exemplul tău de cod, care nu pare să facă nimic cu caseta combo odată ce a fost creată. Sau valorile nu sunt în ordinea pe care o doriți? Sau aveai nevoie de chei în loc de valori în caseta combo? Cred că majoritatea ar fi de acord că oricare dintre cele 3 răspunsuri de până acum ar trebui să funcționeze bine, așa că probabil că există o problemă cu aplicarea răspunsului sau o altă problemă în altă parte, cu care am putea să vă ajutăm dacă ne dați mai multe informații. –  > Por Bert F.
  • ooohh…i stupiding =). Doar o singură întrebare cum se obține HashMap<this->String, HashMap<SomeInnerKeyType, String>> –  > Por Mediator.
  • @simply denis – Mi-e teamă că nu înțeleg întrebarea ta? Întrebi cum obții o referință la HashMap<String, HashMap<SomeInnerKeyType, String>>? Dacă bucla dvs. se află într-o metodă, ar trebui să puteți folosi this.selects sau pur și simplu selects? În caz contrar, ar trebui să transmiteți harta ca parametru la metoda care conține bucla. Sau întrebi cum să obții un anumit parametru interior al buclei? HashMap<SomeInnerKeyType, String> pentru o anumită cheie (this->String?) Ar trebui să folosiți selects.get(keyString). Dacă am înțeles complet greșit, vă rog să mă lămuriți. –  > Por Bert F.
akhil_mittal

Fluxuri Java 8

Împreună cu forEach metodă care acceptă un expresie lambda avem, de asemenea, și flux API-uri, în Java 8.

Iterați peste intrări (utilizând forEach și 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);
        });

Avantajul fluxurilor este că pot fi paralelizate cu ușurință și pot fi utile atunci când avem la dispoziție mai multe procesoare. Trebuie pur și simplu să folosim parallelStream() în loc de stream() de mai sus. În cazul fluxurilor paralele, este mai logic să folosim forEach ca forEachOrdered nu ar face nicio diferență în ceea ce privește performanța. Dacă dorim să iterăm peste chei, putem utiliza sample.keySet() iar pentru valori sample.values().

De ce forEachOrdered și nu forEach cu fluxuri?

De asemenea, fluxurile oferă forEach dar comportamentul lui forEach este în mod explicit nedeterminist, în timp ce forEachOrdered execută o acțiune pentru fiecare element al acestui flux, în metoda ordinea de întâlnire a fluxului în cazul în care fluxul are o ordine de întâlnire definită. Deci forEach nu garantează că ordinea va fi păstrată. Pentru mai multe informații, consultați și acest link.

Oliver Charlesworth

Puteți itera peste un HashMap (și multe alte colecții) folosind un iterator, de ex:

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

...

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

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

Comentarii

  • Nu pot cu un astfel de design până la nivelul de mai jos –  > Por Mediator.
  • @Da, puteți. Puteți crea un iterator interior bazat pe it.next(). –  > Por Oliver Charlesworth.
panahi

În general, fac același lucru ca și cx42net, dar nu creez în mod explicit o Intrare.

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

Aceasta mi se pare cea mai intuitivă, cred că am prejudecăți împotriva iterației peste valorile unei hărți.

icyrock.com

Utilizați entrySet,

/**
 *Output: 
D: 99.22
A: 3434.34
C: 1378.0
B: 123.22
E: -19.08

B's new balance: 1123.22
 */

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MainClass {
  public static void main(String args[]) {

    HashMap<String, Double> hm = new HashMap<String, Double>();

    hm.put("A", new Double(3434.34));
    hm.put("B", new Double(123.22));
    hm.put("C", new Double(1378.00));
    hm.put("D", new Double(99.22));
    hm.put("E", new Double(-19.08));

    Set<Map.Entry<String, Double>> set = hm.entrySet();

    for (Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }

    System.out.println();

    double balance = hm.get("B");
    hm.put("B", balance + 1000);

    System.out.println("B's new balance: " + hm.get("B"));
  }
}

vedeți exemplul complet aici:

Comentarii

  • Funcționează definitiv, eu îl folosesc în fiecare zi 🙂 Ce anume nu funcționează? După cum ați HashMap<String, HashMap>, ai avea nevoie de două bucle – una pentru HashMap-ul exterior și una pentru HashMap-ul interior. Btw – ar trebui să tastezi definitiv al doilea HashMap – nu știu ce stochezi în el, dar ceva de genul HashMap<String, HashMap<string, String>> – deși, din exemplul tău, se pare că ar trebui să folosești HashMap<String, Set<String>>. Și încă un lucru – folosiți interfețe: Map<String, Map> atunci când puteți. –  > Por icyrock.com.

Tags: