Collectors.toMap空指针问题

简介: Collectors.toMap空指针问题

社会上崇敬名人,于是以为名人的话就是名言,却忘记了他所以得名是那一种学问和事业。 —— 鲁迅

对于Collectors.toMap,我们使用时如果value为空,则会抛出空指针,因为底层调用的Map.merge函数

如果我们想避免该问题,就可以使用collect去处理,例如我给hutool提交的这个PR一样

原先:

StreamUtil.of(collection, isParallel).collect(Collectors.toMap(key, value, (l, r) -> l));

现在:

StreamUtil.of(collection, isParallel).collect(HashMap::new, (HashMap<K, V> m, E v) -> m.put(key.apply(v), value.apply(v)), HashMap::putAll);

完整函数:

/**
 * @param collection 需要转化的集合
 * @param key        E类型转化为K类型的lambda方法
 * @param value      E类型转化为V类型的lambda方法
 * @param isParallel 是否并行流
 * @param <E>        collection中的泛型
 * @param <K>        map中的key类型
 * @param <V>        map中的value类型
 * @return 转化后的map
 */
public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value, boolean isParallel) {
  if (CollUtil.isEmpty(collection)) {
    return Collections.emptyMap();
  }
  return StreamUtil.of(collection, isParallel).collect(HashMap::new, (HashMap<K, V> m, E v) -> m.put(key.apply(v), value.apply(v)), HashMap::putAll);
}

当然,对于hutool中另一个函数CollStream.toIdentityMap也同理

原来:

StreamUtil.of(collection, isParallel).collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));

现在:

StreamUtil.of(collection, isParallel).collect(HashMap::new, (HashMap<K, V> m, V v) -> m.put(Opt.ofNullable(v).map(key).get(), v), HashMap::putAll);

完整代码:

/**
 * 将collection转化为类型不变的map<br>
 * <B>{@code Collection<V>  ---->  Map<K,V>}</B>
 *
 * @param collection 需要转化的集合
 * @param key        V类型转化为K类型的lambda方法
 * @param isParallel 是否并行流
 * @param <V>        collection中的泛型
 * @param <K>        map中的key类型
 * @return 转化后的map
 */
public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key, boolean isParallel) {
  if (CollUtil.isEmpty(collection)) {
    return Collections.emptyMap();
  }
  return StreamUtil.of(collection, isParallel)
      .collect(HashMap::new, (HashMap<K, V> m, V v) -> m.put(Opt.ofNullable(v).map(key).get(), v), HashMap::putAll);
}

实际发生场景如下:我查询出用户与好友关联关系,并想获取Map<好友编号, 好友备注>时,使用该函数导致NPE,因为默认使用的

Map.merge不允许空值,而我此处场景下,允许未给好友备注,也就是允许null值,故 修复了该问题

相关文章
|
7月前
|
消息中间件 canal Java
如何保证Canal+MQ同步消息的顺序性?
如何保证Canal+MQ同步消息的顺序性?
|
缓存 Java Android开发
【OOM异常排查经验】
【OOM异常排查经验】
645 0
|
2月前
|
SQL 分布式计算 大数据
SparkSQL 入门指南:小白也能懂的大数据 SQL 处理神器
在大数据处理的领域,SparkSQL 是一种非常强大的工具,它可以让开发人员以 SQL 的方式处理和查询大规模数据集。SparkSQL 集成了 SQL 查询引擎和 Spark 的分布式计算引擎,使得我们可以在分布式环境下执行 SQL 查询,并能利用 Spark 的强大计算能力进行数据分析。
|
10月前
|
自然语言处理 前端开发 Serverless
基于阿里云通义千问开发编程辅助与代码生成工具
随着软件开发需求的增加,编程辅助与代码生成工具成为开发者提高效率的利器。这类工具能够根据用户描述生成代码片段、协助调试、生成自动化脚本等,大大减少重复性劳动。阿里云通义千问作为一款先进的大语言模型,具备强大的自然语言处理和代码生成能力,非常适合用于开发这样的工具。
1167 3
|
Java Android开发
IDEA设置项目编码格式【修改为GBK 或 UTF-8】
这篇文章介绍了在IntelliJ IDEA中如何设置项目编码格式,包括将项目编码修改为GBK或UTF-8的详细步骤和图解。
19402 12
IDEA设置项目编码格式【修改为GBK 或 UTF-8】
|
消息中间件 存储 Java
RabbitMQ之延迟队列(手把手教你学习延迟队列)
【1月更文挑战第12天】延时队列,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列的。
4545 104
IDEA查看方法继承关系,如何在Idea中查看某个方法被谁调用、当前方法调用了哪些方法
这篇文章介绍了如何在IntelliJ IDEA中查看方法的继承关系和方法调用链,包括使用鼠标操作和快捷键`Ctrl+Alt+h`来查看一个方法被谁调用以及当前方法调用了哪些方法的具体步骤和界面说明。
|
存储 缓存 Java
集合中的对象在传输中变成了LinkedHashMap解决方案
集合中的对象在传输中变成了LinkedHashMap解决方案
|
Java 数据库
成功解决: 加上 @Transient 仍然报 Unknown column ‘goods_list‘ in ‘field list‘
这篇文章讨论了在SpringBoot结合MyBatis-Plus框架中,当实体类中包含另一个实体类的集合,而这个集合字段在数据库中不存在时,如何避免由此引发的错误。文章提供了两种解决方法:一是使用`@TableField(exist = false)`注解明确指定该字段在数据库中不存在;二是使用`transient`关键字,但要注意`transient`关键字在Java中默认就是被忽略的,不需要加`@Transient`注解。文章最后展示了问题解决的效果。