Given a Map where Person has a String getName() (etc) method on it, how can I turn the Map into a Map where the String is obtained from calling Person::getName()?
Pre-Java 8 I'd use
Map byNameMap = new HashMap<>();
for (Map.Entry person : people.entrySet()) {
byNameMap.put(person.getKey(), person.getValue().getName());
}
but I'd like to do it using streams and lambdas.
I can't see how to do this in a functional style: Map/HashMap don't implement Stream.
people.entrySet() returns a Set> which I can stream over, but how can I add a new Entry to the destination map?
解决方案
With Java 8 you can do:
Map byNameMap = new HashMap<>();
people.forEach((k, v) -> byNameMap.put(k, v.getName());
Though you'd be better off using Guava's Maps.transformValues, which wraps the original Map and does the conversion when you do the get, meaning you only pay the conversion cost when you actually consume the value.
Using Guava would look like this:
Map byNameMap = Maps.transformValues(people, Person::getName);
EDIT:
Following @Eelco's comment (and for completeness), the conversion to a map is better down with Collectors.toMap like this:
Map byNameMap = people.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, (entry) -> entry.getValue().getName());