after hours of research I can't find the solution of my problem. I have a Map<String, List<User>>
and I want to remove some items of the Map based on some values in the List.
I have to following User class
public class User {
public String firstName,
public Integer age
public boolean is50() {
return this.age.equals(50);
}
}
And I have a Map as this :
Map<String, List<User> myMap = new HashMap<>();
myMap.put("A", new ArrayList<>());
myMap.get("A").add(new User("John", 50));
myMap.get("A").add(new User("Bob", 30));
myMap.put("B", new ArrayList<>());
myMap.get("B").add(new User("Sam", 25));
myMap.get("B").add(new User("Sarah", 56));
myMap.put("C", new ArrayList<>());
myMap.get("C").add(new User("Gill", 15));
myMap.get("C").add(new User("Jim", 20));
Now, I want to remove entries of Map if at least One user in a List age is 50. Also, I want to use Java 8 features to achieve this.
I've found that there is a removeIf
function but I can't make it works with Lists.
I've tried something like this :
Map<String, List<User> filteredMap = myMap
.enrySet()
.removeIf(e -> e.getValue()
.stream()
.filter(user -> user::is50)
.collect(Collectors.toList())
Of course that doesn't work :(
The excepted Output is a filteredMap with only B et C keys with all users (the A key must be deleted because John has 50 yrs old)
Thx for your help and hope it is clear ;)
This should do the trick:
myMap.entrySet()
.removeIf(e -> e.getValue()
.stream()
.anyMatch(User::is50));
Do note that entrySet() modifications (removeIf) affect the map backed by the entry set. So, you either have to make a copy of the map and run this on the copy, or let the first map (myMap
) be modified.
As for making copies of your map, you can simply do:
Map<String, List<User>> copy = new HashMap<>(myMap);
EDIT:
As per @Holger's suggestion, the better way to do in-place removal is as following:
myMap.values()
.removeIf(v -> v.stream()
.anyMatch(User::is50));
The reason this is better is fourfold:
getValue
since values
provides the value set directly.values
and a value than between entrySet
and a value.peek
outside of debugging is an anti-pattern, despite sometimes being more concise).values
is backed by the map.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