Java 8 stream map on entry set
java, java-stream, lambda
Solution
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())));
}
Problem
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?