Collectors.toMap可以将 List 转换成 Map,toMap 有三个重载方法
重载方法一:
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return new CollectorImpl<>(HashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_ID);
}
重载方法二:
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
重载方法三:
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapFactory) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapFactory, accumulator, mapMerger(mergeFunction), CH_ID);
}
keyMapper:key的映射函数valueMapper:value的映射函数mergeFunction:当key冲突时,调用的合并方法mapFactory:Map工厂,创建Map,结果会放入该Map
如果其中一个 value 为 null,toMap 方法就会报 NullPointerException 错误,运行以下代码就会报错。
List<Person> personList = new ArrayList<>();
personList.add(new Person(1, "a"));
personList.add(new Person(2, "b"));
personList.add(new Person(3, null));
Map<Integer, String> personMap = personList.stream().collect(Collectors.toMap(Person::getId, Person::getName));
在重载方法一中的uniqKeysMapAccumulator(keyMapper, valueMapper),会要求 value 不为 null
private static <T, K, V>
BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return (map, element) -> {
K k = keyMapper.apply(element);
V v = Objects.requireNonNull(valueMapper.apply(element));
V u = map.putIfAbsent(k, v);
if (u != null) throw duplicateKeyException(k, u, v);
};
}
重载方法二调用重载方法三,所以直接看重载方法三。有一个accumulator参数,也是一个函数式接口,调用map#merge方法,传入了key 和 value。
在HashMap#merge方法,如果 value 为 null,直接报 NPE 异常
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (value == null || remappingFunction == null)
throw new NullPointerException();
// 省略...
}
在TreeMap#merge方法,Objects#requireNonNull会要求 value 不为 null,否则也是报 NPE 异常
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
// 省略...
}
文章详细介绍了Java中Collectors类的toMap方法的三个重载版本,用于将List转换为Map。在处理过程中,如果value为null,会导致NullPointerException。方法一和方法二通过uniqKeysMapAccumulator要求value非空,而方法三则在HashMap或TreeMap的merge方法中对value进行非空检查。
1万+

被折叠的 条评论
为什么被折叠?



