Y a-t-il un moyen d'initialiser et de remplir élégamment une valeur multiple Map<K,Collection<V>>
en utilisant l'API de flux de Java 8?Création idiomatique d'une carte à valeurs multiples à partir d'un flux en Java 8
Je sais qu'il est possible de créer une seule valeur Map<K, V>
en utilisant les fonctionnalités Collectors.toMap(..)
:
Stream<Person> persons = fetchPersons();
Map<String, Person> personsByName = persons.collect(Collectors.toMap(Person::getName, Function.identity()));
Malheureusement, cette méthode ne fonctionne pas bien pour les clés éventuellement non uniques, telles que le nom d'une personne.
D'autre part, il est possible de remplir une valeur multiple Map<K, Collection<V>>
utilisant Map.compute(K, BiFunction<? super K,? super V,? extends 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;
}));
est-il pas un moyen plus concis de le faire, par exemple en initialisant et en remplissant la carte dans une déclaration?
est-ce pas un usage manuel cas pour groupingBy? –
@PatrickParker Oui, vous et Holger avez raison. Je n'ai jamais beaucoup utilisé cette méthode. – errantlinguist
@Patrick Parker: oui, c'est un cas d'utilisation parfait pour 'groupingBy', qui [est une application pratique de' computeIfAbsent'] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk /openjdk/8u40-b25/java/util/stream/Collectors.java#908). Bien sûr, du côté de l'application, 'groupingBy' est préférable. – Holger