2013-08-22 17 views
9

Mam następujący HashMap gdzie key jest String a value jest reprezentowany przez ArrayList:Jak sprawdzić czy wartość w HashMap istnieć

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

Mam też inny ArrayList<String> foods wdrożone w mojej aplikacji.

Moje pytanie brzmi: Jaki byłby najlepszy sposób sprawdzenia, czy mój HashMap zawiera specyfikację String z mojego drugiego numeru ArrayList?

Próbowałem bez powodzenia:

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

jest Twój 'klucz "wartość powinna być konkretnym ciągiem znaków? –

+0

Tak. Powinien to być określony ciąg. –

+0

"Bez powodzenia nie jest opisem problemu. – EJP

Odpowiedz

12

Dlaczego nie:

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

A jeśli masz do iteracji w całym ArrayList<String>, zamiast szukać jednej wartości określonej tylko:

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

Edytuj

Ostatnim razem zaktualizowałem to za pomocą niektórych idiomów Java 8.

Interfejs API Java 8 strumieni umożliwia bardziej deklaratywny (i prawdopodobnie elegancki) sposób obsługi tego typu iteracji.

Na przykład, oto (nieco zbyt rozwlekły) drogą do osiągnięcia tego samego:

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

... i tu jest prostszy sposób, aby osiągnąć ten sam, początkowo iteracji wartości productsMap zamiast treści 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

Dziękuję bardzo! –

+0

Nie ma za co :) – Mena

+0

Mam pewne dodatkowe wątpliwości w wartościach "myString", które nie są całkowicie znane, wiem tylko o myStri .Jak to zweryfikować lub znaleźć pełną wartość, używając pewnych znaków jako "myStri". Czy możesz mi pomóc proszę. @ Mena.or anyone – goku

9

trzeba użyć metody containsKey(). Aby to zrobić, po prostu uzyskasz tabelę skrótu, z której chcesz uzyskać klucz, a następnie użyj metody , która zwróci wartość boolean, jeśli tak się stanie. Przeszuka całą mapę hashMap bez konieczności powtarzania każdego elementu. Jeśli masz klucz, możesz po prostu pobrać wartość.

To może wyglądać:

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

Oto link do Android

Z Androidem docs:

public boolean containsKey (klawisz Object) Dodane w poziomie API 1

Powoduje potwierdzenie, czy ta mapa zawiera określony klucz. Parametry klucz klawisz do wyszukania.Zwraca

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

dlaczego to nazywa sięKey zamiast wartości containsValue? Jeśli celem jest wiedzieć, czy zawiera wartość, czy nie. – aldok

+0

dlaczego nie używać 'productsMap.containsValue ("myKey") ' – Tim

+1

@aldok Nie ma nic w twoim pytaniu o patrzenie w wartości. – EJP

1

Spróbuj

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

Jeśli chcesz Java 8 sposób to zrobić, można zrobić coś takiego:

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

albo coś takiego:

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

Obie powinny dawać prawie taki sam wynik.

3

Spróbuj tego:

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

Oto metoda, która testuje próbki dla obu scenariuszy. Wyszukiwanie przedmiotów w kluczach MAP i szukać również dla pozycji w wykazach każdego wpisu mapy:

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

Oto wynik:

productsMap nie zawiera klucz o nazwie Jabłko

productsMap nie zawiera klucz o nazwie Squash

productsMap zawiera klucz o nazwie owoce

Searching na wartościach lista dla kluczowych owoców ..

lista productMap wynikających z najważniejszych owoców zawiera artykuł Apple

lista productMap wynikających z najważniejszych owoców nie zawiera elementu Squash

lista productMap wynikających z najważniejszych owoców nie zawiera artykuł owoce

wyszukiwania na wartościach lista kluczowych dla wegetarian ..

lista productMap wynikających kluczowych warzywa nie zawiera artykuł Apple

lista productMap wynikających kluczowych warzyw zawiera artykuł Squash

lista productMap wynikających kluczowych warzywa nie zawierają punkt owoce

1
hashMap.containsValue("your value"); 

sprawdzi, czy HashMap zawiera wartość

+0

Nie ma takiej metody. – EJP

+0

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

Powiązane problemy