Another way to do this is to remove the values you don't want from the transformed Map
:
Map<String, Integer> output = input.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> Integer.parseInt(e.getValue()),
(a, b) -> { throw new AssertionError(); },
HashMap::new
));
output.values().removeIf(v -> v % 2 != 0);
This assumes you want a mutable Map
as the result, if not you can probably create an immutable one from output
.
If you are transforming the values into the same type and want to modify the Map
in place this could be alot shorter with replaceAll
:
input.replaceAll((k, v) -> v + " example");
input.values().removeIf(v -> v.length() > 10);
This also assumes input
is mutable.
I don't recommend doing this because It will not work for all valid Map
implementations and may stop working for HashMap
in the future, but you can currently use replaceAll
and cast a HashMap
to change the type of the values:
((Map)input).replaceAll((k, v) -> Integer.parseInt((String)v));
Map<String, Integer> output = (Map)input;
output.values().removeIf(v -> v % 2 != 0);
This will also give you type safety warnings and if you try to retrieve a value from the Map
through a reference of the old type like this:
String ex = input.get("a");
It will throw a ClassCastException
.
You could move the first transform part into a method to avoid the boilerplate if you expect to use it alot:
public static <K, VO, VN, M extends Map<K, VN>> M transformValues(
Map<? extends K, ? extends VO> old,
Function<? super VO, ? extends VN> f,
Supplier<? extends M> mapFactory){
return old.entrySet().stream().collect(Collectors.toMap(
Entry::getKey,
e -> f.apply(e.getValue()),
(a, b) -> { throw new IllegalStateException("Duplicate keys for values " + a + " " + b); },
mapFactory));
}
And use it like this:
Map<String, Integer> output = transformValues(input, Integer::parseInt, HashMap::new);
output.values().removeIf(v -> v % 2 != 0);
Note that the duplicate key exception can be thrown if, for example, the old
Map
is an IdentityHashMap
and the mapFactory
creates a HashMap
.