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.
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
.
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);
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()))