聊聊 HashMap 中的一个“坑”!

作者 | 王磊
来源 | Java中文社群(ID:javacn666)
转载请联系授权(微信ID:GG_Stone)
最近公司新来了一个小伙伴,坑问了磊哥一个比较“奇怪”的聊聊问题,这个问题本身的坑难度并不大,但比较“隐蔽”,聊聊那究竟是坑什么问题呢?接下来我们一起来看。
起因
最近公司的聊聊系统要增加一个新的列表展示功能,功能本身难度并不大,坑但遇到了一个很“可怪”的聊聊问题。小伙伴在执行查询列表时,坑明明已经使用了 order by 进行排序了,聊聊但最终查询出来的坑数据却还是乱的。
预期中的聊聊(正确)结果:

现实中的(非预期)结果:

那到底是哪里出现了问题呢?
问题展示
为了方便展示,我把复杂的坑业务程序简化成了以下代码:
import java.util.HashMap; public class App { public static void main(String[] args) { HashMap<String, Object> result = getList(); result.forEach((k, v) -> { System.out.println(k + ":" + v); }); } // 查询方法(简化版) public static HashMap<String, Object> getList() { HashMap<String, Object> result = new HashMap<>(); // 最终返回的结果集 // 伪代码:从数据库中查询出了数据,然后对数据进行处理之后,聊聊存到了 for (int i = 1; i <= 5; i++) { result.put("2022-10-" + i,坑 "hello java" + i); } return result; } }以上程序的执行结果如下:

预期的结果应该是按时间的先后顺序展示的,服务器租用如下图所示:

PS:以上示例代码中,插入元素的顺序是有序的(从 1 到 5),相当于实际业务场景中的 order by。
原因分析
既然原数据使用了 order by 排序,那么原数据肯定是没问题的,那问题就只会出现在返回集 HashMap 上,然后我们再把焦点放到 HashMap 上, 瞬间醒悟,哦,原来如此。HashMap 使用的是哈希方式进行存储的,因此存入和读取的顺序可能是不一致的,这也说 HashMap 是无序的集合,所以会导致插入的(或 order by 的)顺序,与最终展示的顺序不一致。
解决方案
经过上面的香港云服务器分析我们顺利找到了问题,那接下来就是制定相应的解决方案了,我想到的解决方案有两个:
稍微麻烦一点但正确的解决方案:将返回的不确定数据类型 HashMap 改为确定的数据类型,比如 List; 简单一点但并不是最优的解决方案:将无序的 HashMap 改为有序的 LinkedHashMap,此方案的优点是,只需要改动一个单词就可以解决整个问题了。第一种解决方案大家都懂这里就不演示了,接下来咱们使用第二种解决方案将上面的问题改造一下,最终的实现代码如下:
import java.util.HashMap; import java.util.LinkedHashMap; public class App { public static void main(String[] args) { HashMap<String, Object> result = getList(); result.forEach((k, v) -> { System.out.println(k + ":" + v); }); } // 查询方法(简化版) public static HashMap<String, Object> getList() { HashMap<String, Object> result = new LinkedHashMap<>(); // 最终返回的结果集 // 伪代码:从数据库中查询出了数据,然后对数据进行处理之后,存到了 for (int i = 1; i <= 5; i++) { result.put("2022-10-" + i, "hello java" + i); } return result; } }以上程序的执行结果如下:

从上述结果可以看出,当使用 LinkedHashMap 替代了 HashMap 之后,返回的顺序就能和插入的顺序保持一致了。
LinkedHashMap 的魔力
为什么 HashMap 是云南idc服务商无序的,而 LinkedHashMap 却是有序的呢?
这要从二者的实现说起了,LinkedHashMap 属于 HashMap 的子类,所以 LinkedHashMap 除了拥有 HashMap 的所有特性之后,还具备自身的一些扩展属性,其中就包括 LinkedHashMap 中额外维护了一个双向链表,这个双向链表就是用来保存元素的(插入)顺序的,这也是为什么 LinkedHashMap 可以实现访问顺序和插入顺序一致的原因了。
总结
本文演示了 HashMap 作为返回类型时隐藏的一个小“坑”,因为 HashMap 本身是无序的,所以它会导致查询顺序和插入顺序不一致的问题,对应的解决方案有两种:使用确定的数据类型来替代 HashMap,比如 List,或者使用有序的 LinkedHashMap 来替代无序的 HashMap。
相关文章
神舟战神电脑装系统教程(一步步教你如何为神舟战神电脑装系统)
摘要:对于购买了神舟战神电脑的用户来说,装系统是必不可少的一项任务。本文将以详细的步骤和说明,教你如何为神舟战神电脑装系统,让你能够轻松上手。1.确定装系统所需材料在进行系统...2025-11-05小米Naot2手机的全面评测(体验小米Naot2手机,感受卓越性能与创新设计)
摘要:近年来,手机市场竞争激烈,各大品牌纷纷推出各具特色的新品。其中,小米作为中国本土手机品牌,在技术创新和性价比方面一直备受关注。而小米Naot2手机作为其最新推出的一款旗舰机型,更是...2025-11-05AMD7400K(解析AMD7400K处理器的关键特性及应用领域)
摘要:随着计算机技术的不断进步,处理器作为计算机的核心组件,其性能和稳定性对于用户的体验至关重要。AMD7400K处理器作为一款高性能处理器,具有出色的多线程处理能力和高效能的图形性能,...2025-11-05戴尔灵越7748s评测(探索戴尔灵越7748s的性能、设计和功能特点)
摘要:随着科技的进步,笔记本电脑已经成为人们工作和娱乐的必备工具。戴尔作为一家知名电脑制造商,在市场上推出了众多性能强悍、设计精美的产品。本文将深入评测戴尔灵越7748s笔记本电脑,探索...2025-11-05如何应对台式电脑设置密码提示错误问题(解决密码提示错误的有效方法)
摘要:在使用台式电脑时,我们常常需要设置密码来保护个人隐私和重要信息的安全。然而,有时候我们可能会面临密码提示错误的问题,这不仅会让我们无法正常登录,还可能导致数据丢失或信息泄露的风险。...2025-11-05- 摘要:在现代社会中,音乐已经成为了人们生活的一部分。无论是在休闲娱乐还是工作学习,我们都无法离开音乐的陪伴。而一款好的耳机,不仅可以让我们更好地享受音乐的魅力,还能提高我们的生活品质。而...2025-11-05

最新评论