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
    @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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

01-黑马程序员大数据开发

一. Hadoop概述 1. 什么是大数据 &#xfeff;狭义上&#xff1a;对海量数据进行处理的软件技术体系&#xfeff;广义上&#xff1a;数字化、信息化时代的基础支撑&#xff0c;以数据为生活赋 2. 大数据的核心工作&#xff1a; &#xfeff;存储&#xff1a;妥善保存海量待…

Http---HTTP 请求报文

1. HTTP 请求报文介绍 HTTP最常见的请求报文有两种: GET 方式的请求报文POST 方式的请求报文 说明: GET: 获取web服务器数据POST: 向web服务器提交数据 2. HTTP GET 请求报文分析 HTTP GET 请求报文效果图: GET 请求报文说明: ---- 请求行 ---- GET / HTTP/1.1 # GET请…

Qt WebAssembly开发环境配置

目录 前言1、下载Emscripten SDK2、 安装3、环境变量配置4、QtCreator配置5、运行示例程序总结 前言 本文主要介绍 Qt WebAssembly 开发环境的配置。Qt for Webassembly 可以使Qt应用程序在Web上运行。WebAssembly&#xff08;简称Wasm&#xff09;是一种能够在虚拟机中执行的…

内存管理学习

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

【原理图PCB专题】原理图图纸锁定/解锁与PCB文件加密方式

在工作中我们会遇到需要冻结原理图进行评审和加密图纸防止被他人盗用的需求。那么在OrCAD Capture中如何对图纸进行锁定与解锁,如何在Allegro中对PCB工程进行加密呢? 原理图锁定与解锁 打开原理图,在图纸中单击右键,选择lock/unlock就可以进行锁定与解锁。 锁定时图纸图…

PostGIS学习教程十四:更多的空间连接

PostGIS学习教程十四&#xff1a;更多的空间连接 在上一节中&#xff0c;我们看到了ST_Centroid(geometry)和ST_Union([geometry])函数&#xff0c;以及一些简单的示例。在本节中&#xff0c;我们将用它们做一些更详细的事情。 提示&#xff1a;写完文章后&#xff0c;目录可以…

OCC:第一个程序,对话框中显示一个BOX

1. OCC库的获取 从github上获取 gitgithub.com:tpaviot/oce.git&#xff0c;自己编译官网获取二进制包&#xff08;获取下来的只有release 版本的&#xff0c;而且VS版本不一定适合自己&#xff09;官网源码&#xff0c;然后自己编译&#xff08;稍微折腾点&#xff0c;建议按…

带大家做一个,易上手的家常辣椒炒肉

先拿一块猪肉泡水解冻 然后 拿四个螺丝椒 螺丝椒切片 放入四个干辣椒 猪肉切片 三瓣左右蒜 如下图大小的一块姜 姜蒜切小块 将辣椒单独倒入锅中 翻炒出辣味 闻到辣味后将辣椒捞出 这里千万不要洗锅不然就把辣味洗掉了 直接起锅烧油 下入肉片翻炒 猪肉变色后 下入姜蒜…

UG阵列面、阵列集合特征和阵列特征的区别

阵列面 对面进行阵列&#xff0c;当实体中被切除特征的时候可以使用阵列面&#xff0c;当这个命令去阵列一个实体的时候&#xff0c;阵列的是一个片体&#xff0c;优点是速度快&#xff0c;缺点是功能较简单&#xff1b; 阵列几何特征 对实体进行阵列&#xff0c;可以一次性选…

Linux 一键部署二进制Gitea

gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…

数据结构 | 东北大学厦门大学期末试卷查漏补缺

Prim变型算法&#xff08;不会&#xff09; 有人给出求解最小生成树的另外一种算法&#xff1a;将连通图中的边按其权值从大到小顺序逐个删除直至不可再删&#xff0c;删除要遵循的原则是&#xff1a;保证在删除该边后各个顶点之间应该是连通的。请问该算法是正确的吗&#xf…

ElasticSearch 的基础概念与入门使用

ElasticSearch 的基础概念与入门使用 前言 elasticsearch 是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大的功能&#xff0c;可以帮助我们从海量的数据中快速找到需要的内容。 例如&#xff1a; 在 Github 中搜索代码 在电商网站搜索商品 在 Google 搜索答案 …

过采样技术基本原理

本文介绍过采样技术基本原理。 过采样技术在ADC信号采集过程中使用还是比较多的。某些使用场景下&#xff0c;对采样速度要求并不是那么高&#xff08;或ADC采样速度过剩&#xff09;&#xff0c;但是想要获取较高的分辨率&#xff0c;就会用到这种技术&#xff0c;如针对温度…

设计模式:循序渐进走入工厂模式

文章目录 前言一、引入二、简单工厂模式1.实现2.优缺点3.扩展 三、工厂方法模式1.实现2.优缺点 四、抽象工厂模式1.实现2.优缺点3.使用场景 五、模式扩展六、JDK源码解析总结 前言 软件设计模式之工厂模式。 一、引入 需求&#xff1a;设计一个咖啡店点餐系统。 设计一个咖啡类…

在MongoDB中使用数组字段和子文档字段进行索引

本文主要介绍在MongoDB使用数组字段和子文档字段进行索引。 目录 MongoDB的高级索引一、索引数组字段二、索引子文档字段 MongoDB的高级索引 MongoDB是一个面向文档的NoSQL数据库&#xff0c;它提供了丰富的索引功能来加快查询性能。除了常规的单字段索引之外&#xff0c;Mong…

只更新软件,座椅为何能获得加热功能?——一文读懂OTA

2020年&#xff0c;特斯拉发布过一次OTA更新&#xff0c;车主可以通过这次系统更新获得座椅加热功能。当时&#xff0c;这则新闻震惊了车圈和所有车主&#xff0c;彼时的大家还没有把汽车当作可以“升级”的智能设备。 如今3年过去了&#xff0c;车主对各家车企的OTA升级早已见…

华为OD机试真题-园区参观路径-2023年OD统一考试(C卷)

题目描述:园区某部门举办了Family Day,邀请员工及其家属参加;将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角;家属参观园区时,只能向右和向下园区前进;求从起始园区到终点园区会有多少条不同的参观路径; 输入描述:第一行为园区长和宽;后面每一行…

【ITK库学习】使用itk库进行图像配准:内插器(插值)

目录 1、itkNearestNeighborInterpolateImageFunction 最近点插值2、itkLinearInterpolateImageFunction 线性插值3、itkBSplineInterpolateImageFunction B样条插值4、itkWindowedSincInterpolateImageFunction 窗口化Sinc插值5、itkRayCastInterpolateImageFunction 投射插值…

充电桩MOS如何选型

• 充电桩是大功率 AC-DC 转换电源&#xff0c;用于给新能源电动汽车快速充电。 • 目前非 800V系统充电桩采用三相维也纳整流 LLC 电路&#xff0c;其中 PFC 整流可以采用二 极管&#xff0c;PFC 升压可以采用650V IGBT 或者 SJ MOSFET&#xff0c; LLC 采用 650V SJ MOSFET。…

Megatron模型并行研究

Megatron模型并行研究 1. 技术调研 a. Megatron-LM Megatron-LM针对的是特别大的语言模型&#xff0c;使用的是模型并行的训练方式。但和普通的模型并行不同&#xff0c;他采用的其实是张量并行的形式&#xff0c;具体来说就是将一个层切开放到不同的GPU上&#xff0c;属于层…