java.lang.IllegalStateException: Duplicate key

news2025/2/1 11:49:32

序言

最近监控扫描出我们项目的某些异常信息,报错java.lang.IllegalStateException: Duplicate key xxx,看到异常来自stream流,然后定位看了一下是某位同事的代码使用stream流把List转Map集合出现重复的key异常信息。List集合A对象来源于某个接口的返回,使用A对象的uuid成员变量作为key,理论上uuid作为唯一标识不应该有重复。
所以正确的做法是:
1)找该接口对应责任人,定位看List对象A的uuid为什么出现重复;
2)查看本项目代码中的异常来源;

java.util.stream.Collectors

Java 8版本引入Stream流式数据处理方式,使得可以对集合进行更简单高效的操作。
API文档链接如下:

  • oracle.com/javase/8/doc/stream
  • microsoft.com/api/java.util.stream.collectors

异常根因

首先看一段示例代码,

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class DuplicateKeyDemo {

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Builder
    private static class Employee {
        private int identifierId;

        private String name;

        private int age;
    }

    public static void main(String[] args) {
        List<Employee> employList = new ArrayList<>();
        employList.add(new Employee(1, "Mike", 25));
        employList.add(new Employee(2, "Mary", 26));
        employList.add(new Employee(3, "Jack", 28));
        employList.add(new Employee(4, "Tom", 23));
        employList.add(new Employee(5, "Lucy", 21));
        employList.add(new Employee(6, "Jim", 26));
        employList.add(new Employee(7, "David", 29));
        employList.add(new Employee(8, "Jack", 22));
        employList.add(new Employee(8, "Jack", 25));
        Collector<Employee, ?, Map<String, Integer>> collector = Collectors.toMap(Employee::getName, Employee::getAge);
        Map<String, Integer> nameAgeIgnoreRepeatMap = employList.stream().collect(collector);
        System.out.println(nameAgeIgnoreRepeatMap);
    }
}

抛出的异常信息如下,

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 28
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1254)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.hust.zhang.stream.DuplicateKeyDemo.main(DuplicateKeyDemo.java:43)

直接点到HashMap的merge方法时,Map中已经存在28岁的Jack,新来的一条数据是22岁的Jack,那么在执行remappingFunction.apply(old.value, value)时就会报错java.lang.IllegalStateException: Duplicate key 28
在这里插入图片描述

解决方案

如果假设我们在这个Map里就是可以被覆盖,那么应该怎么做?

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class DuplicateKeyDemo {

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Builder
    private static class Employee {
        private int identifierId;

        private String name;

        private int age;
    }

    public static void main(String[] args) {
        List<Employee> employList = new ArrayList<>();
        employList.add(new Employee(1, "Mike", 25));
        employList.add(new Employee(2, "Mary", 26));
        employList.add(new Employee(3, "Jack", 28));
        employList.add(new Employee(4, "Tom", 23));
        employList.add(new Employee(5, "Lucy", 21));
        employList.add(new Employee(6, "Jim", 26));
        employList.add(new Employee(7, "David", 29));
        employList.add(new Employee(8, "Jack", 22));
        employList.add(new Employee(8, "Jack", 25));
        Collector<Employee, ?, Map<String, Integer>> antiCollisionCollector = Collectors.toMap(Employee::getName,
                Employee::getAge, (oldValue, newValue) -> oldValue);
        Map<String, Integer> nameAgeMap = employList.stream().collect(antiCollisionCollector);
        System.out.println(nameAgeMap);
    }
}

针对原来代码改了一行,在Collectors.toMap方法后面追加(oldValue, newValue) -> oldValue,表示当出现冲突时取初始出现值,如下图,执行remappingFunction.apply(old.value, value)方法时返回初始值28
在这里插入图片描述
如果改成(oldValue, newValue) -> newValue则在本示例中返回重复对象的末尾值25

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1329368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python命名规范中的[单/双][前导/后缀]下划线小结

如图所示 出处 Single and Double Underscores in Python Names

「C/C++ 01」 深拷贝和浅拷贝

目录 一、概念 1. 浅拷贝 2. 深拷贝 3. 深浅拷贝问题 4. 总结 二、在C的类中实现深拷贝 1. 拷贝构造函数 中实现深拷贝 a. 自己开辟一个新空间&#xff0c;然后将内容拷贝到新空间 b. 借助构造函数来实现深拷贝 2. operator 中实现深拷贝 a. 自己开辟一个新空间&#xff0c;…

JAVA版的鸿鹄云商B2B2C:多商家入驻直播商城系统特性解析 商城免 费搭建

鸿鹄云商 b2b2c产品概述 【b2b2c平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级b2b2c电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消…

pyqt5实现wget下载视频文件的进度条显示

简介&#xff1a; 最近在写一个项目&#xff0c;用到了wget下载视频&#xff0c;为了更好的视觉效果&#xff0c;所以使用pyqt5中QProgressBar来实现下载进度条。当视频开始下载就会弹出下载进度条&#xff0c;下载完成后进度条消失。效果如下图; 具体代码实现 &#xff1a; …

Sobit:将BRC20资产桥接到Solana ,加速铭文市场的火热

2023 年 1 月份后&#xff0c;比特币 Ordinals 协议出现后为铭文赛道的出现奠定了基础&#xff0c;它以聪为单位将比特币分成份&#xff0c;并在每一聪上攥刻不同的信息以达到非同质化资产的效果&#xff0c;而此后包括 BRC20 在内的诸多采用了 Ordinals 方案的应用不断面向市场…

生成式AI大模型对人类进化的影响

你是不是发现每天的工作都离不开ChatGPT之类的语言生成模型&#xff1f;离不开类似Midjourney的图像生成模型&#xff1f;离不开一些设计类的AI辅助工具&#xff1f;如果是&#xff0c;那说明你已经逐步被AI侵蚀了&#xff0c;你的创造力也正在逐渐下降&#xff0c;大模型正在剥…

使用通道和模式

通过通道、选择语句和最佳实践掌握 Go 中的并发编程 并发编程是构建高效和响应迅速的软件的强大范例。Go&#xff0c;也被称为 Golang&#xff0c;通过通道提供了一种健壮且优雅的解决方案来进行并发通信。在这篇文章中&#xff0c;我们将探讨通道的概念、它们在并发编程中的作…

Qt配置opencv,cmake编译参考笔记,已成功

Qt版本&#xff1a;Qt5.14.2 opencv&#xff1a;4.5.4&#xff08;不要用4.5.5&#xff01;&#xff01;很坑别问我为什么知道&#xff09; cmake&#xff1a;下的最新版本 前言&#xff1a;为什么非得要用cmake编译呢&#xff1f;跳过cmake不好吗&#xff1f; 之前用的opencv…

pickle反序列化

文章目录 基础知识pickle简介可序列化对象object.__reduce__() 函数 pickle过程详细解读opcode简介pickletools 漏洞利用利用思路如何手写opcode 工具pker实战例题[MTCTF 2022]easypickle[HZNUCTF 2023 preliminary]pickle 基础知识 pickle简介 与PHP类似&#xff0c;python也…

内存管理学习

内存管理 在计算系统中&#xff0c;通常存储空间分为两种&#xff1a;内部存储空间和外部存储空间。 内部存储空间通常访问速度比较快&#xff0c;能够按照变量地址随机访问&#xff0c;也就是我们通常所说的RAM&#xff08;随机存储器&#xff09;&#xff0c;可以把它理解为…

两种方法解决win10开机慢,经验分享

方法一&#xff1a; 1、按快捷键“winR”打开 运行窗口。 2、这时候输入“msconfig”后 &#xff0c;点击“确定”或者按“ENTER”键。 3、这时候会打开一个名为“系统配置”的窗口&#xff0c; 在“常规”选项框下 勾选“有选择的启动”下的“加载系统服务”和“加载启动项”。…

Python的环境搭建环境配置()

Python 环境搭建 一,下载Python 1.去官网 www.python.org 下载环境 2.如图点击Download 3.选择Windows 4.如图直接下载 5.直接勾选 6.后面就一直默认选项 Win11 安装目录 不能放在C盘的ProgramFIle路径下 二,测试环境是否安装成功 1.winR 输入cmd 2.输入python --versio…

[已解决] Ubuntu远程桌面闪退+登录显示“远程桌面由于数据加密错误 , 这个会话将结束“

两个月前&#xff0c;由于跑代码在Ubuntu配置环境&#xff0c;乱七八糟的下载了很多东西&#xff0c;导致了一系列问题..... 问题1 Ubuntu远程桌面闪退 实验室有两台服务器&#xff0c;IP后三位分别为141和142&#xff0c;其中141在输入密码后立即闪退&#xff0c;142可以正常…

110基于matlab的混合方法组合的极限学习机和稀疏表示进行分类

基于matlab的混合方法组合的极限学习机和稀疏表示进行分类。通过将极限学习机&#xff08;ELM&#xff09;和稀疏表示&#xff08;SRC&#xff09;结合到统一框架中&#xff0c;混合分类器具有快速测试&#xff08;ELM的优点&#xff09;的优点&#xff0c;且显示出显着的分类精…

华为鸿蒙开发适合哪些人学习?

随着鸿蒙系统的崛起&#xff0c;越来越多的人开始关注鸿蒙开发&#xff0c;并希望成为鸿蒙开发者。然而&#xff0c;鸿蒙开发并不适合所有人&#xff0c;那么哪些人最适合学习鸿蒙开发呢&#xff1f;本文将为您总结鸿蒙开发适合的人群。 一、具备编程基础的人 学习鸿蒙开发需要…

python报错A value is trying to be set on a copy of a slice

加入.copy()即可避免该报错提示 原代码&#xff1a; df5df4.drop_duplicates() print(df5.shape)df5[班型中文名称]df5[班型名称]-A print(df5.head()) 输出结果&#xff1a; 修改后代码&#xff1a; df5df4.drop_duplicates().copy() print(df5.shape)df5[班型中文名称]df…

MyBatis关联查询(三、多对多查询)

MyBatis关联查询&#xff08;三、多对多查询&#xff09; 需求&#xff1a;查询角色及角色赋予的用户信息。 分析&#xff1a;一个用户可以拥有多个角色&#xff0c;一个角色也可以赋予多个用户&#xff0c;用户和角色为双向的一对多关系&#xff0c;多对多关系其实我们看成是…

2. 行为模式 - 命令模式

亦称&#xff1a; 动作、事务、Action、Transaction、Command 意图 命令模式是一种行为设计模式&#xff0c; 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中&#xff0c; 且能实现可撤销…

SVM —— 代码实现

SMO 算法的实现步骤&#xff1a; 代码如下&#xff1a; import numpy as np import matplotlib.pyplot as plt import seaborn as sns import random# 设置中文字体为宋体&#xff0c;英文字体为 times new roman sns.set(font"SimSun", style"ticks", fo…

从零开始创建GPTs 人人都可以编写自己的ChatGPT产品

在这个人工智能迅猛发展的时代&#xff0c;GPT&#xff08;生成式预训练变换器&#xff09;已经成为一项令人兴奋的技术&#xff0c;它打开了创意和知识的新大门。无论你是一名编程新手、一位热爱探索的学生&#xff0c;还是对未来充满好奇的专业人士&#xff0c;GPTs都可以为你…