Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter a map by its values in Java 8?

Tags:

java

java-8

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?

like image 782
Nazila Avatar asked Nov 01 '15 06:11

Nazila


People also ask

How do I filter a map based on values in Java 8?

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

Can we use filter and map together in Java 8?

With Java 8, you can convert a Map. entrySet() into a stream , follow by a filter() and collect() it.

Can we use filter and map together in Java?

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.

What is the difference between filter and map in Java 8?

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.


2 Answers

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.

like image 88
Eran Avatar answered Sep 23 '22 19:09

Eran


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); 
like image 27
Matthias Braun Avatar answered Sep 23 '22 19:09

Matthias Braun