web-dev-qa-db-fra.com

Check in Map of list s'il existe une valeur pour une clé spécifique Java 8

En Java 7 j'ai

Map<String, List<String>> m = new HashMap<String, List<String>>();
boolean result = false;
m.put("Name1", Arrays.asList("abc*1"));
m.put("Name2", Arrays.asList("abc@*1"));


for (Map.Entry<String, List<String>> me : m.entrySet()) {
    String key = me.getKey();
    List<String> valueList = me.getValue();
    if (key.equals("Name2"){
        System.out.print("Values: ");
        for (String s : valueList) {
            if(s.contains("@"){
                result = true;
            }
        }
    }
} 

Comment puis-je obtenir un résultat booléen pour Name2 s'il contient @ en utilisant une correspondance?

J'ai essayé d'utiliser le code suivant mais je ne sais pas comment utiliser l'informatique pour une clé spécifique 

result = m.values().stream().anyMatch(v -> v.contains("@"))
4
Marinescu Raluca

Vous pouvez simplement utiliser m.get("Name2"), placer le résultat (nullable) dans une Optional puis utiliser un mappage:

boolean result = Optional.ofNullable(m.get("Name2"))
    .map(l -> l.stream().anyMatch(s -> s.contains("@")))
    .orElse(false);

Cela est préférable pour boucler sur le jeu d'entrées, puisque HashMap.get est O(1) et que l'itération sur le jeu d'entrées est O (n).

3
Michael

Faites ce qui suit:

boolean result = m.getOrDefault("Name2", Collections.emptyList()).stream()
    .anyMatch(i -> i.contains("@"));

Si la variable Map contient une clé correcte, vérifiez si l'un de ses éléments de la valeur List contient le caractère en question. Si la variable Map ne contient pas la clé, simulez la variable Collection vide qui ne contient rien du tout et le résultat est automatiquement évalué en tant que false.

Edit: Comme @Michael l’a suggéré, l’utilisation de Collections.emptyList() est un meilleur choix que new ArrayList<>().

7
Nikolas

Qu'en est-il de 

String name = "Name1";
boolean result= m.containsKey(name) && m.get(name).stream().anyMatch(a -> a.contains("@"));
2
YCF_L

Essaye ça:

boolean result = m.entrySet().stream()
    .filter(e -> e.getKey().equals(Name2))
    .map(Map.Entry::getValue)
    .flatMap(List::stream)
    .anyMatch(s -> s.contains("@"));
2
Bohemian

créez un flux à partir de la entrySet(), puis indiquez vos critères dans la anyMatch:

result = m.entrySet()
          .stream()
          .anyMatch(v -> Objects.equals("Name2", v.getKey()) && 
               v.getValue().stream().anyMatch(s -> s.contains("@")));

ou en utilisant getOrDefault:

result = m.getOrDefault("Name2", Collections.emptyList())
          .stream()
          .anyMatch(s -> s.contains("@"));
1
Aomine

Ajoutez simplement la condition de filtre correcte:

m.entrySet()
.stream()
.anyMatch(entry-> entry.getKey().equals(Name2) && 
   entry.getValue()
.stream()
.anyMatch(string -> string.contains("@"))
.getValue();
1
Vinay Prajapati

Vous devez d’abord filtrer en fonction de la clé requise, puis vous pouvez utiliser anyMatch pour déterminer si la valeur de cette clé contient un élément avec un caractère '@':

result = m.entrySet ()
          .stream ()
          .filter (e->e.getKey ().equals (Name2))
          .anyMatch (e->e.getValue ().stream ().anyMatch (s->s.contains ("@")));
1
Eran

Et ça 

Map<Integer, String> result = hmap.entrySet() 
                             .stream() 
                             .filter(map -> map.getKey().equals("Name2")) 
                             .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()))
                             .orElse(null);

Cela gère également NoSuchElementException.

0
Vinay Hegde