有没有一种优雅的方法可以使用Java 8的流API初始化和填充多值Map<K, Collection<V>>
?
我知道可以使用Collectors.toMap(..)
功能创建单值Map<K, V>
:
Stream<Person> persons = fetchPersons();
Map<String, Person> personsByName = persons.collect(Collectors.toMap(Person::getName, Function.identity()));
不幸的是,对于可能存在非唯一键(如人名)的情况,该方法效果不佳。
另一方面,可以使用Map.compute(K, BiFunction<? super K,? super V,? extends V>>
来填充一个多值的Map<K, Collection<V>>
:
Stream<Person> persons = fetchPersons();
Map<String, Set<Person>> personsByName = new HashMap<>();
persons.forEach(person -> personsByName.compute(person.getName(), (name, oldValue) -> {
Set<Person> result = (oldValue== null) ? new HashSet<>() : oldValue;
result.add(person);
return result;
}));
有没有更加简洁的方法来完成这个任务,比如说一条语句中完成Map的初始化和填充?
groupingBy
的一个完美应用案例,它是computeIfAbsent
的实际应用。当然,在应用程序方面,使用groupingBy
更可取。 - Holger