【发布时间】:2017-08-08 11:48:47
【问题描述】:
有没有办法使用 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;
}));
没有更简洁的方法可以做到这一点,例如通过在一个语句中初始化和填充地图?
【问题讨论】:
-
这不是 groupingBy 的教科书用例吗?
-
@PatrickParker 是的,你和 Holger 是对的。我从来没有使用过这种方法。
-
@Patrick Parker:是的,这是
groupingBy的完美用例,is a practical application ofcomputeIfAbsent。当然,在应用端,groupingBy更可取。
标签: java dictionary java-stream multimap