-
我把一个可变对象当 HashMap 的 key 存了进去、后来改了这个对象里参与 hashCode 计算的一个字段,再用它去 map 里 get 竟然返回 null,可我遍历这个 map 明明能看到这条记录还在里面,我对着这个又在又取不出来的幽灵键排查了大半天才想通问题出在哪的深度复盘
我有个实体类 Key 重写了 equals 和 hashCode、都基于它的 id 字段,把一个 Key 对象当键连着一个值 put 进了 HashMap,一切正常。后来业务逻辑里我修改了这个 Key 对象的 id(它可变、有 setter),再拿这个对象去 map.get(key) 想取回当初存的值,结果返回 null。我懵了:这个 key 没删过啊,containsKey 也是 false,可…- 0
- 0
-
我重写了 equals 让两个字段相同的对象相等,把它当 HashMap 的 key 存进去,再用一个一模一样的 key 去取却拿到了 null:一次 Java 只重写 equals 没重写 hashCode 的深度复盘
我用一个自定义的 OrderKey(含 userId 和 date)当 HashMap 的 key,为了让两个字段都相同的 key 被视为同一个 key,我重写了 equals。可线上诡异:map.put(key1, value) 存进去后,用一个字段完全相同的新 key2 去 get 居然返回 null,而 key1.equals(key2) 明明是 true。查清才明白:我只重写了 equal…- 0
- 0
-
一个重写了 equals 却忘了重写 hashCode 的 Java 对象,放进 HashSet 后既去不了重、也再也取不出来:一次违背 equals-hashCode 契约的深度复盘
给 User 重写了 equals(id 相同即相等),放进 HashSet 却没去重、用 id 相同的 User 去 map.get 竟返回 null——东西放进去了却取不出来。根因是只重写了 equals、没重写 hashCode:两个 equals 相等的对象,hashCode 却用 Object 默认实现(基于地址)而不同,违背了'equals 相等则 hashCode 必相等&…- 0
- 0
-
我给一个类重写了 equals 判断两个对象内容相等,用它做 HashMap 的 key 存了又取,取出来的竟然永远是 null,我对着只重写 equals 不重写 hashCode 这个坑排查大半天的复盘
一个堪称 Java 面试必问、实战必踩的经典坑,隐蔽在它看起来天经地义:我明明定义了两个对象在什么情况下相等,HashMap 却像没看见一样固执地说找不到。需求是个缓存:有个坐标点类 Point,我希望只要 x、y 相同两个 Point 就算相等,用 Point 做 key 把计算结果缓存进 HashMap。为此我认真重写了 equals(x、y 相同就相等),但没重写 hashCode。结果 p…- 0
- 0
-
我自定义对象重写了 equals 判断相等,放进 HashSet 却还是有重复、用它当 HashMap 的 key 也取不到值,我对着 equals 和 hashCode 排查了大半天的复盘
写去重逻辑,自定义类 User 重写了 equals 规定 id 相同就算同一用户,把一堆 User 放进 HashSet 去重、又用 User 当 HashMap 的 key。结果诡异:id 相同的两个 User 放进 HashSet 竟没去重、用 id 相同的 User 去 HashMap get 竟取不到值返回 null。盯着 equals 反复看明明重写了 id 相同返回 true 啊为啥…- 0
- 0
-
我用自定义对象当 HashMap 的 key,两个字段完全一样的对象却被当成了不同的键、get 永远返回 null,我对着这个去重失效的 Map 排查了大半天的复盘
我用自定义的 Point(有 x、y)当 HashMap 的 key,put(new Point(1,2),"A") 后再用另一个内容一模一样的 new Point(1,2) 去 get,竟返回 null;HashSet 放两个相同的 Point 也没去重、都进去了。内容明明完全相同,怎么就认不出?深挖才懂:我没重写 equals 和 hashCode——不重写时继承 Obje…- 2
- 0
-
我在多线程里共用一个 HashMap 做缓存,某天线上 CPU 突然飙到 100% 卡死、线程全堆在 HashMap.get 上,我抓着线程栈复盘了大半天的惨痛经历
我的服务用一个 HashMap 当本地缓存、多线程并发读写,平时好好的,某天线上 CPU 毫无征兆飙到 100% 且降不下来、服务卡死。jstack 一抓头皮发麻:好几个线程死死卡在 HashMap.get 的 for 循环里出不来——死循环。深挖才懂:HashMap 线程不安全,多线程并发 put 同时触发扩容,JDK7 头插法迁移节点时并发把链表指针搞乱、接成 A→B→A→B 的环形链表,此后…- 0
- 0
-
我把对象放进 HashMap,转头用一个"一模一样"的 key 却取不出来:Java 里没重写 hashCode/equals 埋下的那颗雷的复盘
put 进去一个 Point(1,2) 对应的值,转头用内容一模一样的 new Point(1,2) 去 get,却返回 null。根因是我用自定义对象当 HashMap 的 key,却没重写 hashCode/equals——Object 默认的这两个方法比的是内存地址而非内容,两个内容相同的对象算出不同的 hashCode、定位到不同的桶,自然取不到。这篇从 HashMap 靠 hashCod…- 0
- 0
-
缓存命中率离奇趴在 0%:Java equals 与 hashCode 避坑
一个跑得好好的 Java 服务,某次我顺手看了眼缓存命中率监控,当场愣住:命中率常年趴在接近 0% 的地方,缓存等于白做,内存里那个缓存 map 倒越涨越大,光占地方不干活。打日志一比对更迷惑——两个 key 在日志里长得一模一样,map.get(key) 却就是返回 null。扒开那个作为 key 的自定义类,真相经典得让我有点不好意思:它重写了 equals 让业务上相等的对象被判相等,却偏偏…- 0
- 0
HashMap
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!









