I have a Java Map that I\'d like to transform and filter. As a trivial example, suppose I want to convert all values to Integers then remove the odd entries.
Map
One way to solve the problem with much lesser overhead is to move the mapping and filtering down to the collector.
Map output = input.entrySet().stream().collect(
HashMap::new,
(map,e)->{ int i=Integer.parseInt(e.getValue()); if(i%2==0) map.put(e.getKey(), i); },
Map::putAll);
This does not require the creation of intermediate Map.Entry
instances and even better, will postpone the boxing of int
values to the point when the values are actually added to the Map
, which implies that values rejected by the filter are not boxed at all.
Compared to what Collectors.toMap(…)
does, the operation is also simplified by using Map.put
rather than Map.merge
as we know beforehand that we don’t have to handle key collisions here.
However, as long as you don’t want to utilize parallel execution you may also consider the ordinary loop
HashMap output=new HashMap<>();
for(Map.Entry e: input.entrySet()) {
int i = Integer.parseInt(e.getValue());
if(i%2==0) output.put(e.getKey(), i);
}
or the internal iteration variant:
HashMap output=new HashMap<>();
input.forEach((k,v)->{ int i = Integer.parseInt(v); if(i%2==0) output.put(k, i); });
the latter being quite compact and at least on par with all other variants regarding single threaded performance.