J'ai le HashMap
suivant où le key
est un String
et le value
est représenté par un ArrayList
:
HashMap<String, ArrayList<String>> productsMap = AsyncUpload.getFoodMap();
J'ai aussi un autre ArrayList<String> foods
implémenté dans mon application.
Ma question est: Quelle serait la meilleure façon de savoir si mon HashMap
contient un String
spécifique de mon second ArrayList
?
J'ai essayé sans succès:
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);
}
}
Pourquoi pas:
// fast-enumerating map's values
for (ArrayList<String> value: productsMap.values()) {
// using ArrayList#contains
System.out.println(value.contains("myString"));
}
Et si vous devez répéter sur l'ensemble ArrayList<String>
, au lieu de rechercher une seule valeur spécifique:
// 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));
}
}
Modifier
La dernière fois, j'ai mis à jour cela avec quelques idiomes Java 8.
L'API Java 8 streams permet une manière plus déclarative (et sans doute élégante) de gérer ces types d'itérations.
Par exemple, voici un moyen (un peu trop verbeux) pour obtenir le même résultat:
// 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)
)
)
... et voici une manière plus simple de faire la même chose, en itérant initialement les valeurs productsMap
au lieu du contenu de 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)
)
Vous devez utiliser la méthode containsKey()
. Pour ce faire, vous obtenez simplement le hashMap dont vous voulez retirer la clé, puis utilisez la méthode containsKey
, qui retournera une valeur boolean
si c'est le cas. Cela recherchera toute la table de hachage sans avoir à parcourir chaque élément. Si vous avez la clé, vous pouvez simplement récupérer la valeur.
Cela pourrait ressembler à:
if(productsMap.values().containsKey("myKey"))
{
// do something if hashMap has key
}
Voici le lien vers Android
Depuis les documents Android:
public boolean containsKey (Object key) Ajouté au niveau 1 de l'API
Renvoie si cette carte contient la clé spécifiée. Les paramètres saisissent la clé à rechercher. Retour
true if this map contains the specified key, false otherwise.
Essaye ça :
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");
Vérifie si le HashMap contient la valeur
Voici un exemple de méthode qui teste les deux scénarios. Recherche d'éléments dans les clés de la carte et recherche également des éléments dans les listes de chaque entrée de carte:
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);
}
}
}
}
Voici le résultat:
productsMap ne contient pas de clé nommée Apple
productsMap ne contient pas de clé nommée Squash
productsMap contient une clé nommée fruits
Recherche sur les valeurs de liste pour les fruits clés.
la liste de productMap sous les fruits clés contient l'article Apple
la liste de productMap sous les fruits clés ne contient pas d'élément Squash
la liste de productMap sous les fruits clés ne contient pas les fruits de l'article
Recherche sur les valeurs de liste pour les légumes clés.
la liste de productMap sous les légumes clés ne contient pas l'article Apple
la liste de productMap sous les légumes clés contient l'article Squash
la liste de productMap sous les légumes clés ne contient pas de fruits
Essaye ça
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);
}
}
Si vous voulez la manière Java 8 de le faire, vous pouvez faire quelque chose comme ceci:
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;
}
Ou quelque chose comme ça:
private static boolean containsValue(final Map<String, ArrayList<String>> map, final String value){
return map.values().stream().filter(list -> list.contains(value)).findFirst().isPresent();
}
Les deux devraient produire à peu près le même résultat.