簡體   English   中英

從Java 8的流中慣用地創建多值映射

[英]Idiomatically creating a multi-value Map from a Stream in Java 8

有什么方法可以使用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;
}));

還有沒有更簡潔的方法,例如在一個語句中初始化並填充地圖?

如果使用forEach ,那么使用computeIfAbsent代替compute會容易得多:

Map<String, Set<Person>> personsByName = new HashMap<>();
persons.forEach(person ->
    personsByName.computeIfAbsent(person.getName(), key -> new HashSet<>()).add(person));

但是,在使用Stream API時,最好使用collect 在這種情況下,請使用groupingBy而不是toMap

Map<String, Set<Person>> personsByName =
    persons.collect(Collectors.groupingBy(Person::getName, Collectors.toSet());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM