2013-08-22 6 views
9

Ho il seguente HashMap dove il key è un String e la value è rappresentato da un ArrayList:Come verificare se un valore in HashMap esistere

HashMap<String, ArrayList<String>> productsMap = AsyncUpload.getFoodMap(); 

Ho anche un'altra ArrayList<String> foods implementato nella mia applicazione.

La mia domanda è, quale sarebbe il modo migliore per scoprire se il mio HashMap contiene uno specifico String dal mio secondo ArrayList?

ho provato senza successo:

Iterator<String> keySetIterator = productsMap.keySet().iterator(); 
Iterator<ArrayList<String>> valueSetIterator = productsMap.values().iterator(); 

    while(keySetIterator.hasNext() && valueSetIterator.hasNext()){ 
     String key = keySetIterator.next(); 
     if(mArrayList.contains(key)){ 
      System.out.println("Yes! its a " + key); 
     } 
    } 
+0

è la chiave ' 'valore dovrebbe essere la stringa specifica? –

+0

Sì. Dovrebbe essere una stringa specifica. –

+0

'Senza successo non è una descrizione del problema. – EJP

risposta

12

Perché non:

// fast-enumerating map's values 
for (ArrayList<String> value: productsMap.values()) { 
    // using ArrayList#contains 
    System.out.println(value.contains("myString")); 
} 

E se si deve iterare l'intero ArrayList<String>, invece di cercare un valore specifico solo:

// fast-enumerating food's values ("food" is an ArrayList<String>) 
for (String item: foods) { 
    // fast-enumerating map's values 
    for (ArrayList<String> value: productsMap.values()) { 
     // using ArrayList#contains 
     System.out.println(value.contains(item)); 
    } 
} 

Modifica

La volta passata l'ho aggiornato con alcuni idiomi di Java 8.

L'API Java 8 streams consente un modo più dichiarativo (e discutibilmente elegante) di gestire questi tipi di iterazione.

Per esempio, ecco un modo (un po 'troppo prolisso) per ottenere lo stesso:

// iterate foods 
foods 
    .stream() 
    // matches any occurrence of... 
    .anyMatch(
     // ... any list matching any occurrence of... 
     (s) -> productsMap.values().stream().anyMatch(
      // ... the list containing the iterated item from foods 
      (l) -> l.contains(s) 
     ) 
    ) 

... ed ecco un modo più semplice per ottenere lo stesso, inizialmente l'iterazione dei valori productsMap invece del contenuto di foods:

// iterate productsMap values 
productsMap 
    .values() 
    .stream() 
    // flattening to all list elements 
    .flatMap(List::stream) 
    // matching any occurrence of... 
    .anyMatch(
     // ... an element contained in foods 
     (s) -> foods.contains(s) 
    ) 
+0

Grazie mille! –

+0

Prego :) – Mena

+0

Ho qualche dubbio in più sui valori di "myString" non completamente noti, conosco solo myStri. Come verificare che o trovare il valore completo usando contiene alcuni caratteri come "myStri". Potresti aiutarmi per favore. @ Mena.o chiunque – goku

9

è necessario utilizzare il metodo containsKey(). Per fare ciò, è sufficiente ottenere l'hashMap da cui si desidera estrarre la chiave, quindi utilizzare il metodo containsKey, che restituirà un valore boolean se lo fa. Questo cercherà l'intero hashMap senza dover scorrere su ogni oggetto. Se hai la chiave, puoi semplicemente recuperare il valore.

E potrebbe essere simile:

if(productsMap.values().containsKey("myKey")) 
{ 
    // do something if hashMap has key 
} 

Ecco il link per Android

Dalla documentazione Android:

pubblico containsKey booleano (Object key) Aggiunto a livello di API 1

Indica se questa mappa contiene la chiave specificata. Parametri chiave la chiave per la ricerca.Restituisce

true if this map contains the specified key, false otherwise. 
+1

perché si chiama containsKey piuttosto che containsValue? Se lo scopo è sapere se contiene valore o meno. – aldok

+0

perché non utilizzare 'productMap.containsValue ("myKey") ' – Tim

+1

@aldok Nella tua domanda non c'è nulla riguardo alla ricerca dei valori. – EJP

1

Prova questa

Iterator<String> keySetIterator = productsMap.keySet().iterator(); 
Iterator<ArrayList<String>> valueSetIterator = productsMap.values().iterator(); 

    while(keySetIterator.hasNext()){ 
     String key = keySetIterator.next(); 
     if(valueSetIterator.next().contains(key)){ // corrected here 
      System.out.println("Yes! its a " + key); 
     } 
} 
1

Se si desidera che il modo in cui Java 8 di farlo, si potrebbe fare qualcosa di simile:

private static boolean containsValue(final Map<String, ArrayList<String>> map, final String value){ 
    return map.values().stream().filter(list -> list.contains(value)).findFirst().orElse(null) != null; 
} 

O qualcosa di simile:

private static boolean containsValue(final Map<String, ArrayList<String>> map, final String value){ 
    return map.values().stream().filter(list -> list.contains(value)).findFirst().isPresent(); 
} 

Entrambi dovrebbero produrre praticamente lo stesso risultato.

3

Prova questo:

public boolean anyKeyInMap(Map<String, ArrayList<String>> productsMap, List<String> keys) { 
    Set<String> keySet = new HashSet<>(keys); 

    for (ArrayList<String> strings : productsMap.values()) { 
     for (String string : strings) { 
      if (keySet.contains(string)) { 
       return true; 
      } 
     } 
    } 

    return false; 
} 
1

Ecco un metodo di campionamento che i test per entrambi gli scenari. La ricerca di elementi nelle chiavi della mappa e anche cercare elementi nelle liste di ogni voce di mappa:

private static void testMapSearch(){ 

    final ArrayList<String> fruitsList = new ArrayList<String>();   
    fruitsList.addAll(Arrays.asList("Apple", "Banana", "Grapes")); 

    final ArrayList<String> veggiesList = new ArrayList<String>();   
    veggiesList.addAll(Arrays.asList("Potato", "Squash", "Beans")); 

    final Map<String, ArrayList<String>> productsMap = new HashMap<String, ArrayList<String>>(); 

    productsMap.put("fruits", fruitsList); 
    productsMap.put("veggies", veggiesList); 

    final ArrayList<String> foodList = new ArrayList<String>();   
    foodList.addAll(Arrays.asList("Apple", "Squash", "fruits")); 

    // Check if items from foodList exist in the keyset of productsMap 

    for(String item : foodList){ 
     if(productsMap.containsKey(item)){ 
      System.out.println("productsMap contains a key named " + item); 
     } else { 
      System.out.println("productsMap doesn't contain a key named " + item); 
     } 
    } 

    // Check if items from foodList exits in productsMap's values 

    for (Map.Entry<String, ArrayList<String>> entry : productsMap.entrySet()){ 

     System.out.println("\nSearching on list values for key " + entry.getKey() + ".."); 

     for(String item : foodList){ 
      if(entry.getValue().contains(item)){ 
       System.out.println("productMap's list under key " + entry.getKey() + " contains item " + item); 
      } else { 
       System.out.println("productMap's list under key " + entry.getKey() + " doesn't contain item " + item); 
      } 
     }  
    } 
} 

Ecco il risultato:

productsMap non contiene una chiave di nome Apple

productsMap non contiene una chiave denominata Squash

productsMap contiene una chiave denominata frutti

Ricerca su valori di listino per la frutta chiave ..

lista di Lista dei prodotti sotto frutti chiave contiene articoli Apple

lista di Lista dei prodotti sotto frutti chiave non contiene elemento Squash

lista di Lista dei prodotti sotto frutti chiave non contiene frutti voce

Ricerca sui valori della lista per i vegetariani chiave ..

lista di lista dei prodotti sotto verdure chiave non contiene articoli Apple

.210

lista di Lista dei prodotti sotto verdure chiave contiene voce Squash

lista di Lista dei prodotti sotto verdure chiave non contiene frutti voce

1
hashMap.containsValue("your value"); 

controllerà se l'HashMap contiene il valore

+0

Non esiste un tale metodo. – EJP

+0

@EJP https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#containsValue(java.lang.Object) – Tim