java.lang.IllegalStateException: Duplicate key

序言

最近监控扫描出我们项目的某些异常信息,报错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@Builderprivate 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 28at 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@Builderprivate 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.mzph.cn/news/239226.shtml

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

相关文章

C# WPF上位机开发(QT vs WPF)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 最近经常收到朋友们的私信&#xff0c;他们对C# WPF开发很感兴趣&#xff0c;但是呢&#xff0c;正当准备学习的时候&#xff0c;又有人告诉他们应…

网络安全学习-NTFS安全权限、文件共享

NTFS安全权限 权限概述 设置NTFS权限&#xff0c;实现不同用户访问不同对象&#xff08;文件、文件夹&#xff09;的权限分配正确访问权限后&#xff0c;用户才能访问资源设置权限防止资源被篡改、删除 文件系统概述 文件系统就是这个分区的存储格式&#xff0c;不建立文件…

Linux编程环境和软件设施安装

目录 一、Linux编程环境安装 1.yum安装 2. vim安装&#xff08;文本编辑工具&#xff09; 3. lrzsz安装&#xff08;文件上传下载工具&#xff09; &#xff08;1) 搜索lrzsz安装包 &#xff08;2) 在线安装lrzsz &#xff08;3) 测试 二、Linux软件安装 1. 软件安装方…

Ubuntu 常用命令之 history 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 history命令在Ubuntu系统中用于显示用户执行过的命令列表。这个命令在bash shell中非常有用&#xff0c;特别是当你需要记住你之前执行过的命令时。 history命令的参数如下 -c&#xff1a;清除历史记录。-d offset&#xff1a;删…

Linux patch命令

Linux patch命令用于修补文件。 patch指令让用户利用设置修补文件的方式&#xff0c;修改&#xff0c;更新原始文件。倘若一次仅修改一个文件&#xff0c;可直接在指令列中下达指令依序执行。如果配合修补文件的方式则能一次修补大批文件&#xff0c;这也是Linux系统核心的升级…

Python如何生成随机图形验证码

python生成随机图形验证码 使用python生成随机图片验证码,需要使用pillow模块 1.安装pillow模块 pip install pillow 2.pillow模块的基本使用 1.创建图片 from PIL import Image #定义使用Image类实例化一个长为400px,宽为400px,基于RGB的(255,255,255)颜色的图片 img1Ima…

【oracle】【解决方案】ORA-12514:TNS: 监听程序当前无法识别连接描述符中请求的服务 ORA-12541:TNS:无监听程序的错误

今天重新启动服务器后&#xff0c;tomcat启动异常&#xff0c;测试oracle后报错&#xff0c;提示ora-12541:tns:无监听程序 关掉监听服务 打开目录&#xff1a;D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN 修改前配置文件&#xff1a; # listener.ora Net…

win11下配置visual studio 2022+PCL1.13.1

第一部分&#xff1a;visual studio2022 安装 vs官网网址如下&#xff1a;https://visualstudio.microsoft.com/zh-hans/vs/ 第一步&#xff1a;我们打开官网链接&#xff0c;按如下操作点击下载免费版本的exe文件 第二步&#xff1a;打开下载目录下的安装文件进行安装&#…

npm的使用技巧

以下是一些NPM&#xff08;Node Package Manager&#xff09;的使用技巧&#xff1a; 1. **获取帮助**&#xff1a; - 使用 npm help 或者 npm <command> --help 可以获取关于特定命令的帮助信息。 2. **命令自动完成**&#xff1a; - 在 Bash、Zsh 等 shell 中&…

SQL 多字段条件查询

SQL 多字段条件查询 一个数据库表&#xff0c;几十个字段&#xff0c;查找任意字段里包含北京的记录&#xff0c;在 mysql 里这句 sql 应该是这样&#xff1a; SELECT * FROM table WHERE concat(field1,field2,field3……fieldn) like ‘% 北京 %’ 反正是少不了将几十个字…

【论文笔记】3D Gaussian Splatting for Real-Time Radiance Field Rendering

原文链接&#xff1a;https://arxiv.org/abs/2308.04079 1. 引言 网孔和点是最常见的3D场景表达&#xff0c;因其是显式的且适合基于GPU/CUDA的快速栅格化。神经辐射场&#xff08;NeRF&#xff09;则建立连续的场景表达便于优化&#xff0c;但渲染时的随机采样耗时且引入噪声…

五颜六色(0010)

题意 输入一个十六进制数字&#xff08;事实上是三个十六进制的数字&#xff09;&#xff0c;转换成三个十进制数字&#xff0c;这个十六进制数字是两位两位分开计算的 输入三个十进制数字&#xff0c;转换成三个十六进制的数字&#xff0c;一行连在一起输出 输入 150 50 76…

Valgrind:查找内存泄漏

Valgrind作为一款经典的内存检查工具与ASAN功能相似,但也可以与ASAN相互补充,更有利于排查问题。 Ubuntu22.04上安装Valgrind的方法: 1.sudo apt update 2.sudo apt install valgrind Valgrind使用起来很容易,只要通过 $ valgrind --tool=memcheck --leak-check=full ./…

Win11安装ise14.7~不需要虚拟机了~

之前一直无法在win11上安装ise14.7&#xff0c;网上搜索也无果&#xff0c;所有一直vmware虚拟机使用。直到最近看了水木上jesce的回复&#xff0c;试了下果然可以直接安装使用的。 步骤如下即可&#xff1a; 安装时切勿勾选最后一项&#xff0c;Enable WebTalk to send softwa…

微流控芯片建模分析技术与应用”专题研讨会

关于举办“微流控芯片建模分析技术与应用”专题研讨会的通知 会议背景&#xff1a; 微流控芯片&#xff0c;以微米级空间精确操控流体为特色&#xff0c;被誉为“芯片实验室”。凭借微通道和微结构&#xff0c;它实现了样品的快速、高效、自动化处理和分析。因其微型化、集成…

okhttp系列-一些上限值

1.正在执行的任务数量最大值是64 异步请求放入readyAsyncCalls后&#xff0c;遍历readyAsyncCalls取出任务去执行的时候&#xff0c;如果发现runningAsyncCalls的数量大于等于64&#xff0c;就不从readyAsyncCalls取出任务执行。 public final class Dispatcher {private int …

Python (十五)pandas(三)

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

程序员常用英文邮件模板系列之 - 收到用户问题后如何回复用户

我们在做日常系统运维时经常收到来自世界各地的用户关于系统的各种问题&#xff0c;当我们收到问题后需要快速响应用户同时也希望能够收集到更多的issue相关的内容。 如下就提供一个非常通用的模板&#xff0c;FYI. Hi ***, Thank you for contacting ***Support. My name is …

【vtkWidgetRepresentation】第十六期 vtkContourRepresentation(三)

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享vtkContourLineInterpolator接口的源码剖析和实例应用,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 目录 前言 …

Canny函数opencv

Canny函数opencv 在OpenCV中使用Canny函数时&#xff0c;其中的两个参数是用于边缘检测的阈值。具体来说&#xff0c;Canny(imgBlur, imgCanny, 25, 75); 这行代码中的两个阈值有特定的含义&#xff1a; 低阈值 (Low Threshold): 第一个参数25是低阈值。这个阈值用来控制边缘检…