详细解决java中的Collectors.toMap引起的java.lang.IllegalStateException: Duplicate key xxx 的错误

这篇具有很好参考价值的文章主要介绍了详细解决java中的Collectors.toMap引起的java.lang.IllegalStateException: Duplicate key xxx 的错误。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 复现错误


今天,测试在禅道上给我指出一个正式环境bug,如下图所示:

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

java.lang.IllegalStateException: Duplicate key 2

2. 分析错误


根据java.lang.IllegalStateException: Duplicate key 2可知,这是java抛出的存在2个重复键的错误。

如果想要弄清楚错误原因,通过如下几个步骤分析:

  1. 首先,看到这个错误信息,先在本地使用postman测试这个接口,如下图所示:

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

由于涉及到公司的安全,不能把接口展示出来。

由上图可知,本地环境没有问题。

  1. 查看正式环境的日志,如下图所示:

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

由错误的第2行可知,这是stream.Collectors引起出的错误。

继续往下看,找到红框处,这是项目代码错误抛出的的位置。

于是,查看线上的代码如下所示:

xxxRepository.list(new xxxQuery().setXxx(xxxId))
                .stream()
                .collect(Collectors.toMap(xxxEntity::getName, xxxEntity::getId));

由于保密机制,把实际名称,用xxx替换了。

xxxEntity::getName代码猜想:可能是由于数据库存在两个相同的名字,在转化成Map时就会存在相同的Key,从而导致hash异常,如下代码所示:

@Data
@NoArgsConstructor
public class Student {
  private BigDecimal score;
  private String name;
  private Integer id;
  private Integer age;

  @Override
  public String toString() {
    return JSON.toJSONString(this);
  }

  public Student(BigDecimal score, String name, Integer id, Integer age) {
    this.score = score;
    this.name = name;
    this.id = id;
    this.age = age;
  }

  public static void main(String[] args) {
    Student student1 = new Student(new BigDecimal(99.5), "陈希尔", 1, 12);
    Student student2 = new Student(new BigDecimal(88), "陈希尔", 2, 12);

    List<Student> list = new ArrayList();
    list.add(student1);
    list.add(student2);

    Map<String, Integer> collect =
        list.stream().collect(Collectors.toMap(Student::getName, Student::getId));
    Set<String> keys = collect.keySet();
    String sout = "key = %s, value = %s \n";
    keys.forEach(t -> System.out.format(sout, t, collect.get(t)));
  }
}

注意上述的示例代码,下文也是基于此示例代码修改。

输出结果如下图所示:

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

  1. 根据猜想到数据库中查询数据,如下所示:
select
    COUNT(`name`) as nameCount,
    `name`
from
    xxx_table
GROUP BY
    `name`
HAVING
    nameCount >= 2;

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

找到了问题的所在,原来是name重复了,导致这个错误。

在实际应用开发中,我们会常把一个List的查询数据集合转为一个Map,那么在这里的 list.stream().collect()其实就是做了这么一件事情,它是java8stream方式实现的它是以typekey,以entity对象为value构成Map

本错误中的type就是name,而map中的key值是不能重复的,重复会导致hash异常。

3. 解决问题


既然知道了问题的原因,我们可以用如下方式解决:

  1. 删除name重复记录

  2. 修改代码,保证即便有重复的值,也能转化成Map

我们只需要将这行代码:

 Map<String, Integer> collect =
        list.stream().collect(Collectors.toMap(Student::getName, Student::getId));

按如下方式修改即可:

 Map<String, Integer> collect =
        list.stream()
            .collect(
                Collectors.toMap(Student::getName, Student::getId, (entity1, entity2) -> entity1));

此代码等效于:

Map<String, Integer> collect =
        list.stream()
            .collect(
                Collectors.toMap(
                    Student::getName,
                    Student::getId,
                    new BinaryOperator<Integer>() {
                      @Override
                      public Integer apply(Integer entity1, Integer entity2) {
                        return entity1;
                      }
                    }));

修改完后,如下为测试结果:

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

4. 重要补充

 Map<String, Integer> collect =
        list.stream()
            .collect(
                Collectors.toMap(Student::getName, Student::getId, (entity1, entity2) -> entity1));

等效于:

Map<String, Integer> collect =
        list.stream()
            .collect(
                Collectors.toMap(
                    Student::getName,
                    Student::getId,
                    new BinaryOperator<Integer>() {
                      @Override
                      public Integer apply(Integer entity1, Integer entity2) {
                        return entity1;
                      }
                    }));

我们去看toMap的源代码就知道了,如下图所示:

duplicate key错误怎么解决,免费专栏,java,开发语言,后端,lamda

它第三个参数就是函数式接口,因而,我们可以使用lamda表达式来简化代码。文章来源地址https://www.toymoban.com/news/detail-804187.html

到了这里,关于详细解决java中的Collectors.toMap引起的java.lang.IllegalStateException: Duplicate key xxx 的错误的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决Caused by: java.lang.IllegalStateException:

    目录 问题描述 解决方案 1. 修改JVM的-Xss参数 2. 检查循环继承依赖项 3. 更新相关库和依赖 总结 在使用Java开发Web应用程序时,我们有时会遇到​ ​Caused by: java.lang.IllegalStateException​ ​​异常,其中包含一个关于StackOverflow错误的描述。这种错误可能会导致无法完成对Web应用程

    2024年02月03日
    浏览(38)
  • 解决java.lang.IllegalStateException: Duplicate key异常

    项目重启后突然报这个异常 看日志应该是在初始化字典,源代码 这里的操作是把词典list转换成map,然后key冲突。 但我比对了一下数据,没有找到重复的dictValue,报这个错有点莫名其妙。 最后的解决办法参考了其他网友,得以顺利解决,最后上修改后的代码 Collectors.toMap 增

    2024年02月15日
    浏览(37)
  • 已解决java.lang.IllegalStateException: Duplicate key

    已解决java.lang.IllegalStateException: Duplicate key java.lang.IllegalStateException: Duplicate key java.lang.IllegalStateException: Duplicate key 是由于在使用 Map 或 Set 时,试图将一个已经存在的键值或元素添加到集合中而引发的异常。 下滑查看解决方法 要解决这个问题,可以采取以下步骤: 确保你使用

    2024年02月07日
    浏览(32)
  • 已解决java.lang.IllegalStateException异常的正确解决方法,亲测有效!!!

    java.lang.IllegalStateException java.lang.IllegalStateException通常表示程序的当前状态与所期望的状态不符,导致方法的调用无效或不合法。 下滑查看解决方法 要解决这个问题,你可以尝试以下几个方法: 检查代码逻辑:查看在抛出异常之前的代码,确保程序状态符合所期望的条件。特

    2024年02月05日
    浏览(40)
  • Collectors.toMap使用详解

    在实际项目中我们经常会有 List 转 Map 操作,在过去(JAVA8以前)我们可能使用的是 for 循环遍历的方式,这种方式就不做过多赘述。这里主要讲解使用 Collectors.toMap 方式及使用过程需注意的地方,避免踩坑 三个重载的方法如下: 参数含义分别是: keyMapper:Key 的映射函数。 va

    2024年02月11日
    浏览(35)
  • 【Android】okhttp爆java.lang.IllegalStateException: closed的解决方法

    java.lang.IllegalStateException: closed 异常通常是由于OkHttp中的 Response 对象在调用 response.body().string() 后被关闭而导致的。 在代码中,在 onResponse() 方法中如果两次调用了 response.body().string() ,每次调用都会消耗掉响应体并关闭 Response 对象。因此,当第二次调用 response.body().string() 时

    2024年02月12日
    浏览(31)
  • 猫头虎分享已解决Bug | java.lang.IllegalStateException异常的正确解决方法

    博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接 : 🔗 精选专栏 : 《面试题大全》 — 面试准备的宝典! 《IDEA开发秘籍》 — 提升你的IDEA技能! 《100天精通鸿蒙》 — 从Web/安卓到鸿蒙大师! 《100天精通Golang(基础入门篇)》 — 踏入

    2024年03月20日
    浏览(45)
  • Collectors.toMap()的基本使用方法

    介绍: 1、Java 8 流的新类 java.util.stream.Collectors 实现了 java.util.stream.Collector 接口,同时又提供了大量的方法对流 ( stream ) 的元素执行 map and reduce 操作,或者统计操作; 2、Collectors.toMap()是Java8引入的流特性,可以把集合转换为Map集合,转换对象中的key不可重复,重复会报错;

    2024年02月10日
    浏览(49)
  • 解决Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map ‘inteController‘

    出现这个错也可能会出现项目无法启动的错误。完整错误是 一、错误出现原因 :         controller层出现了重复的方法映射                  可以看到图片中两个方法的映射是一样的,这是问题所在 解决方法也很简单,既然已经知道了问题所在那么解决起来也很简单

    2024年02月10日
    浏览(29)
  • Java IDEA java.lang.IllegalStateException: Failed to introspect Class报错原因和解决办法

    发现是因为 org.redisson:redisson.spring.boot.starter 3.10.6这个包引入不进来导致的报错 尝试了clean invalid caches and restart都没法解决后 放大招,查看maven右侧Dependencies每一个点进去看是否有jar包冲突,发现有一个包里有一个redis的包, 怀疑jar包冲突,尝试把这个包exclusion掉,可以成功运

    2024年02月04日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包