I have a map where the values are strings and the keys are lists: Map<String, List<BoMLine>> materials
. I'd like to filter this map by its values; something like this:
materials.entrySet().stream() .filter(a->a.getValue().stream() .filter(l->MaterialDao.findMaterialByName(l.getMaterial()).ispresent)
But it's not working for me. Does anybody have an idea?
If I understand your filtering criteria correctly, you want to check if the filtered Stream you produced from the value List has any elements, and if so, pass the corresponding Map entry to the output Map . Map<String, List<BoMLine>> filtered = materials. entrySet() . stream() .
With Java 8, you can convert a Map. entrySet() into a stream , follow by a filter() and collect() it.
That's all about how to use map and filter in Java 8. We have seen an interesting example of how we can use the map to transform an object to another and how to use filter to select an object based upon condition. We have also learned how to compose operations on stream to write code that is both clear and concise.
Filter takes a predicate as an argument so basically you are validating your input/collection against a condition, whereas a map allows you to define or use a existing function on the stream eg you can apply String.
If I understand your filtering criteria correctly, you want to check if the filtered Stream
you produced from the value List
has any elements, and if so, pass the corresponding Map
entry to the output 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()));
This is assuming MaterialDao.findMaterialByName(l.getMaterial())
returns a boolean
.
Generally, this is how you can filter a map by its values:
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)); }
Call it like this:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With