Collectors.toMap方法

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);
  // 省略...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值