Как фильтровать карту по ее значениям в Java 8?
У меня есть карта, где значения представляют собой строки, а ключи - это списки: Map<String, List<BoMLine>> materials
. Я хотел бы отфильтровать эту карту по ее значениям; что-то вроде этого:
materials.entrySet().stream()
.filter(a->a.getValue().stream()
.filter(l->MaterialDao.findMaterialByName(l.getMaterial()).ispresent)
Но это не работает для меня. У кого-нибудь есть идея?
Спасибо.
Ответы
Ответ 1
Если я правильно понимаю ваши критерии фильтрации, вы хотите проверить, есть ли у фильтрованного Stream
вы создали из List
значений, какие-либо элементы, и если да, передайте соответствующую запись Map
на выходную 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()));
Это предполагает, что MaterialDao.findMaterialByName(l.getMaterial())
возвращает boolean
.
Ответ 2
Как правило, вы можете фильтровать карту по ее значениям:
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));
}
Назовите это так:
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);
Ответ 3
наконец, заставило его работать, мой второй фильтр был совершенно бесполезен, ответ таков:
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()))