Java 8 stream map on entry set
I'm trying to perform a map operation on each entry in a Map
object.
I need to take a prefix off the key and convert the value from one type to another. My code is taking configuration entries from a Map<String, String>
and converting to a Map<String, AttributeType>
(AttributeType
is just a class holding some information. Further explanation is not relevant for this question.)
The best I have been able to come up with using the Java 8 Streams is the following:
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
int subLength = prefix.length();
return input.entrySet().stream().flatMap((Map.Entry<String, Object> e) -> {
HashMap<String, AttributeType> r = new HashMap<>();
r.put(e.getKey().substring(subLength), AttributeType.GetByName(e.getValue()));
return r.entrySet().stream();
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
Being unable to construct an Map.Entry
due to it being an interface causes the creation of the single entry Map
instance and the use of flatMap()
, which seems ugly.
Is there a better alternative? It seems nicer to do this using a for loop:
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
Map<String, AttributeType> result = new HashMap<>();
int subLength = prefix.length();
for(Map.Entry<String, String> entry : input.entrySet()) {
result.put(entry.getKey().substring(subLength), AttributeType.GetByName( entry.getValue()));
}
return result;
}
Should I avoid the Stream API for this? Or is there a nicer way I have missed?
Simply translating the "old for loop way" into streams:
private Map<String, String> mapConfig(Map<String, Integer> input, String prefix) {
int subLength = prefix.length();
return input.entrySet().stream()
.collect(Collectors.toMap(
entry -> entry.getKey().substring(subLength),
entry -> AttributeType.GetByName(entry.getValue())));
}
Please make the following part of the Collectors API:
<K, V> Collector<? super Map.Entry<K, V>, ?, Map<K, V>> toMap() {
return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
}