web-dev-qa-db-fra.com

Comment filtrer une carte par ses valeurs dans Java 8?

J'ai une carte où les valeurs sont des chaînes et les clés sont des listes: Map<String, List<BoMLine>> materials. Je voudrais filtrer cette carte par ses valeurs; quelque chose comme ça:

materials.entrySet().stream()
       .filter(a->a.getValue().stream()
           .filter(l->MaterialDao.findMaterialByName(l.getMaterial()).ispresent)

Mais ça ne marche pas pour moi. Est-ce que quelqu'un a une idée?

Merci.

19
Nazila

Si je comprends bien vos critères de filtrage, vous voulez vérifier si le Stream filtré que vous avez produit à partir de la valeur List a des éléments, et si c'est le cas, passez l'entrée Map correspondante à la sortie Map.

Map<String, List<BoMLine>>
    filtered = materials.entrySet()
                        .stream()
                        .filter(a->a.getValue()
                                    .stream()
                                    .anyMatch(l->MaterialDao.findMaterialByName(l.getMaterial())))
                        .collect(Collectors.toMap(e->e.getKey(),e->e.getValue()));

Cela suppose que MaterialDao.findMaterialByName(l.getMaterial()) renvoie un boolean.

28
Eran

Généralement, voici comment filtrer une carte par ses valeurs:

static <K, V> Map<K, V> filterByValue(Map<K, V> map, Predicate<V> predicate) {
    return map.entrySet()
            .stream()
            .filter(entry -> predicate.test(entry.getValue()))
            .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}

Appelez ça comme ceci:

Map<String, Integer> originalMap = new HashMap<>();
originalMap.put("One", 1);
originalMap.put("Two", 2);
originalMap.put("Three", 3);

Map<String, Integer> filteredMap = filterByValue(originalMap, value -> value == 2);

Map<String, Integer> expectedMap = new HashMap<>();
expectedMap.put("Two", 2);

assertEquals(expectedMap, filteredMap);
16
Matthias Braun

enfin fait fonctionner, mon deuxième filtre était complètement inutile la réponse est comme ça:

Map<String, List<BoMLine>>
filtered = materials.entrySet()
                    .stream()
                    .filter(a -> a
                      .getValue()
                       .stream()
                        .allMatch(
                            b -> MaterialDao.findMaterialByName(
                                    b.getMaterial()).isPresent()))
            .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()))
0
Nazila