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.hqwc.cn/news/293418.html

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

相关文章

鸿蒙ArkTS语言介绍与TS基础语法

1、ArkTS介绍 ArkTS是HarmonyOS主力应用开发语言&#xff0c;它在TS基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等响应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 JS 是一种属于网络的高级脚本语言&#xff0c;已经被广泛用…

FunBox11靶场 安装下载渗透详细教程

一. 下载靶场 官网下载地址 二. 安装 1.导入FunBox11 三.修改键盘布局和修改IP 参考历史文庄FunBox9安装教程 四. 打靶 1.提供arp-scan工具扫描网络主机IP arp-scan -l -i eh1 2.通过nmap 对目标主机进行扫描 nmap -A -p- -T5 172.30.1.134 -A : 启动Os检测&#xff0c;版…

Qt/QML编程学习之心得:在QML工程中添加库(十四)

实现库并且使用库&#xff0c;类似于vc中的静态库library、动态库dll、COM组件等方法一样&#xff0c;在Qt中也经常会使用库&#xff0c;或者将部分功能打包成库。 右击Qt项目&#xff0c;点击add library... 在linux中将.a文件导入&#xff0c;工程会自动在.pro温江中增加相应…

java定义三套场景接口方案

一、背景 在前后端分离开发的背景下&#xff0c;后端java开发人员现在只需要编写接口接口。特别是使用微服务开发的接口。resful风格接口。那么一般后端接口被调用有下面三种场景。一、不需要用户登录的接口调用&#xff0c;第二、后端管理系统接口调用&#xff08;需要账号密…

进程间通信---无名管道

无名管道和有名管道的区别&#xff1a; 无名管道只能用于父进程和子进程之间通信&#xff0c;而有名管道可以用于任意两个进程间通信 管道工作的原理&#xff1a; 切记&#xff1a;无名管道一旦创建完成后&#xff0c;操作无名管道等同于操作文件&#xff0c;无名管道的读端/写…

【泛型中K T V E? Object等分别代表什么含 义】

✅ 泛型中K T V E? Object等分别代表什么含义 ✅ 典型解析✅代码示例 ✅ 典型解析 E - Element (在集合中使用&#xff0c;因为集合中存放的是元素) T-Type (Java 类) K- Key (键) V - Value (值) N - Number (数值类型) ? - 表示不确定的iava类型 (无限制通配符类型) …

react当中生命周期(旧生命周期详解)

新生命周期https://blog.csdn.net/kkkys_kkk/article/details/135156102?spm1001.2014.3001.5501 目录 什么是生命周期 react中的生命周期 旧生命周期 生命周期图示 常用的生命周期钩子函数 初始化阶段 挂载阶段 在严格模式下挂载阶段的生命周期函数会执行两次原因 更…

MyBatis的关联查询!!!(一对一、一对多、多对多)

准备工作&#xff1a; 1.创建Maven工程&#xff0c;还没有配置Maven的和还不会的去看这里啦&#xff1a;maven的下载安装与配置环境变量&#xff01;&#xff01;&#xff01;&#xff08;全网最详细&#xff09;-CSDN博客 Account.java : (pojo类) &#xff08;这里我…

红日靶场-1

实战 &#xff5c; 记一次基础的内网Vulnstack靶机渗透一https://mp.weixin.qq.com/s/A3MIuT7RXTIIPNLjF42OTg 前言 kali一个nat网卡&#xff0c;模拟外网攻击机 win7一个nat网卡&#xff0c;一个VMnet 1网卡&#xff08;仅主机模式&#xff09;&#xff0c;模拟web服务器win2…

TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)

文章目录 接口_可选属性 接口_只读属性 接口_额外的属性检查 接口_ 函数类型 接口_类类型 接口_继承接口 接口_可选属性 接口里的属性不全都是必需的。 有些是只在某些条件下存在&#xff0c;或者根本不存在。 可选属性在应用 “option bags” 模式时很常用&#xff0c;即…

itk中的配准整理

文章目录 Perform 2D Translation Registration With Mean Squares效果:源码: 多模态互信息配准 Perform Multi Modality Registration With Viola Wells Mutual Information效果图源码: Register Image to Another Using Landmarks 通过标记点配准图像效果图源码 Perform 2D T…

探索Qt 6.3:了解基本知识点和新特性

学习目标&#xff1a; 理解Qt6.3的基本概念和框架&#xff1a;解释Qt是什么&#xff0c;它的核心思想和设计原则。学会安装和配置Qt6.3开发环境&#xff1a;提供详细的步骤&#xff0c;让读者能够顺利安装和配置Qt6.3的开发环境。掌握Qt6.3的基本编程技巧&#xff1a;介绍Qt6.…