说到HashMaphashCodeequals ,想必绝大多数人都不会陌生,然而你真的了解这它们的机制么?本文将通过一个简单的Demo还原我自己前不久在 HashMap 上导致的线上问题,看看我是怎么跳进这个坑中去的。

起因

在重构一段旧代码的时候发现有个 HashMap 的key对象没有重写 hashCodeequals 方法,使用IDEA自动重构工具生成后引发线上问题,因为实际重构的旧代码复杂,所以我抽出了一个关于奶酪(Cheese)的Demo还原踩坑场景,看看究竟谁动了我的奶酪

一个奶酪的例子

  • 首先,我们有一个奶酪(Cheese)类
, ), )             n = (tab = resize()).length;         ) & hash]) == ; ; ++binCount) {                     )  &&             (first = tab[(n - ) & hash]) != , ), , ), , ), "nauyus"); Map<Cheese, String> map = new HashMap<>(); map.put(cheese, "something not important"); //一段被我忽略的代码 cheese.setCreator("tom"); System.out.println(map.get(cheese)); 

putHashMap 后,作为 key 的 cheese 对象再次被 set 了值,导致 hashCode 返回结果有了变更,put 奶酪后无法 get 到,奶酪再一次被动了

总结

总结一下踩坑经历,可以得出以下结论:

  1. 如果自定义对象做为Map的键,那么必须重写hashCode和equals。
  2. 尽量使用不可变对象作为map的键,如String。
  3. 即使万分自信的代码,还是跑一下单元测试为好。(血的教训)

还有啊,没事还是少瞎改别人代码吧!

感谢阅读,原创不易,如有启发,点个赞吧!这将是我写作的最强动力!本文不同步发布于不止于技术的技术公众号 Nauyus ,主要分享一些编程语言,架构设计,思维认知类文章, 2019年12月起开启周更模式,每周一篇原创文章,欢迎关注,共同学习成长!

HashMap踩坑实录——谁动了我的奶酪的更多相关文章

  1. JAVA实用案例之文件导出(JasperReport踩坑实录)

    写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...

  2. JasperReport报表导出踩坑实录

    写在最前面 翻了翻博客,因为太忙,已经好久没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六月份的时候写过一篇利用poi文件导入导出的小De ...

  3. 后端路由项目由 gulp 改为 webpack 的踩坑实录

    前言 公司有个后端路由的项目是用 gulp 作为前端自动化构建工具,最近学习了一下 webpack,深感其强大,一狠心将其改成了 webpack 构建,以下是踩坑实录. gulp 先来说说原来的架构. ...

  4. ffmpeg 踩坑实录 添加实时水印(二)

    一.背景介绍 最近领导要求做一个视频录制的相关项目.其中,需要对视频文件进行添加 实时时间水印.于是,我想到了使用之前的ffmpeg来做. 二.ffmpeg实际操作 首先把需要添加水印的视频文件,上传 ...

  5. (最新)VS2015安装以及卸载过程——踩坑实录

    前言 Visual Studio (简称VS)是微软公司旗下最重要的软件集成开发工具产品.是目前最流行的 Windows 平台应用程序开发环境,也是无数人学习编程的入门软件之一.Visual Stud ...

  6. ffmpeg 踩坑实录 安装与视频切片(一)

    这段时间一直在做一个关于视频处理的项目.其中有一块需要切片相关功能.于是采用了ffmpeg来完成相关需求. 第一,ffmpeg的安装. 首先下载官方包,我这里用的是ffmpeg-release-64b ...

  7. windows安装rabbitmq踩坑实录

    最近学习springcloud消息总线需要用到rabbitmq,然后安装的时候踩了一些坑,记录如下: 首先安装rabbitmq之前需要先安装erlang,因为rabbitmq服务端使用erlang写的 ...

  8. Angular2,Springboot,Zuul,Shiro跨域CORS请求踩坑实录

    前言:前后端分离,业务分离,网关路由等已经成为当下web application开发的流行趋势.前端以单页面路由为核心的框架为主体,可以单独部署在nodejs或nginx上.后端以springboot ...

  9. Ubuntu14.04安装PowerDNS踩坑实录

    公司要使用PowerDNS,作为内网域名解析的工具.让我和另一组的同事学一下如何配置及调优.所以先找了两台服务器试着安装一下.这一装就是一个礼拜,经历了大大小小的坑,记下来以后可能需要参考.安装过程如 ...

随机推荐

  1. Project Euler 58: Spiral primes

    从一开始按以下方式逆时针旋转,可以形成一个边长为七的正方形螺旋: 一个有趣的现象是右下对角线上都有一个奇完全平方数,但是更有趣的是两条对角线上的十三个数中有八个数是素数(已经标红),也就是说素数占比为 ...

  2. Markdown基本语法小结

    目录 Typore Markdown基本语法 1.标题 一级标题 二级标题 三级标题 2.字体加粗 3.斜体 4.文本高亮 5.上标 6.下标 7.引用代码 1 8.代码引用2 9.代码引用3 10. ...

  3. 013.Kubernetes二进制部署worker节点Nginx实现高可用

    一 Nginx代理实现kube-apiserver高可用 1.1 Nginx实现高可用 基于 nginx 代理的 kube-apiserver 高可用方案. 控制节点的 kube-controller ...

  4. thinkphp5中取消了3.2版本中的单字母函数,初用tp5可能不大适应,下边给出两者的对应参照表,以便查阅。

    3.2版本 5.0版本 C config E exception G debug L lang T 废除 I input N 废除 D model M db A controller R action ...

  5. 如何基于k8s快速搭建TeamCity(YAML分享)

    前言 最近有朋友基于之前的博客<Docker最全教程之使用TeamCity来完成内部CI.CD流程(十七)>搭建TeamCity时出现了一些问题,由于平常比较忙,没有及时答复,非常抱歉. ...

  6. (C#)WPF:LinearGradientBrush的使用

    在MSDN文档库里可以查到,Rectangle.Fill的类型是Brush.Brush是一个抽象类,凡是以Brush为基类的类都可作为Fill属性的值.Brush的派生类有很多: * SolidCol ...

  7. 【并发编程】Java中的原子操作

    什么是原子操作 原子操作是指一个或者多个不可再分割的操作.这些操作的执行顺序不能被打乱,这些步骤也不可以被切割而只执行其中的一部分(不可中断性).举个列子: //就是一个原子操作 int i = 1; ...

  8. leetcode-242 判断两个字符串是不是 Anagram ?

    题目描述 假设给定两个字符串 s 和 t, 让我们写出一个方法来判断这两个字符串是否是字母异位词? 字母异位词就是,两个字符串中含有字母的个数和数量都一样,比如: Example 1: Input: ...

  9. HTML页面插入图片,使用background还是img标签

    很多新手在刚开始学习HTML标签的时候,老师一定会教你 <img src="xxx.png"/> 这种引入图片格式,第二天学习css的时候,老师又会教你给div等元素添 ...

  10. vue中动态加载img

    想实现动态加载图片,当点击“首页”时,图片变色 代码如下: <mt-tabbar v-model="selected" fixed class="border-1p ...