简体   繁体   中英

How to verify if a value in HashMap exist

I have the following HashMap where the key is a String and the value is represented by an ArrayList :

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

I also have another ArrayList<String> foods implemented in my application.

My question is, What would be the best way to find out if my HashMap contains a Specific String from my second ArrayList ?

I have tried without success:

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

Why not:

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

And if you have to iterate over the whole ArrayList<String> , instead of looking for one specific value only:

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

Edit

Past time I updated this with some Java 8 idioms.

The Java 8 streams API allows a more declarative (and arguably elegant) way of handling these types of iteration.

For instance, here's a (slightly too verbose) way to achieve the same:

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

... and here's a simpler way to achieve the same, initially iterating the productsMap values instead of the contents of 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)
    )

You need to use the containsKey() method. To do this, you simply get the hashMap you want the key out of, then use the containsKey method, which will return a boolean value if it does. This will search the whole hashMap without having to iterate over each item. If you do have the key, then you can simply retrieve the value.

It might look something like:

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

Here is the link to Android

From the Android docs:

public boolean containsKey (Object key) Added in API level 1

Returns whether this map contains the specified key. Parameters key the key to search for. Returns

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

Try this :

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;
}
hashMap.containsValue("your value");

将检查HashMap是否包含值

Try this

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

If you want the Java 8 way of doing it, you could do something like this:

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

Or something like this:

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

Both should produce pretty much the same result.

Here's a sample method that tests for both scenarios. Searching for items in map's keys and also search for items in the lists of each map entry:

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

Here's the result:

productsMap doesn't contain a key named Apple

productsMap doesn't contain a key named Squash

productsMap contains a key named fruits

Searching on list values for key fruits..

productMap's list under key fruits contains item Apple

productMap's list under key fruits doesn't contain item Squash

productMap's list under key fruits doesn't contain item fruits

Searching on list values for key veggies..

productMap's list under key veggies doesn't contain item Apple

productMap's list under key veggies contains item Squash

productMap's list under key veggies doesn't contain item fruits

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM