HashMap无序的这个小“坑“,一不小心就翻车了

大家好,我是一航;

昨天一位粉丝朋友和我聊天,说遇到了一个莫名奇妙的问题,让我帮着分析一下;经过他的一轮描述,发现是一个HashMap元素顺序小’坑’;但是一不留神,老司机也容易在这里翻车。

一句话来描述一下他的问题:明明我数据库语句使用了Order by进行了排序,日志中也看到数据是按顺序查出来了,但业务层收到数据依然还是乱序的呢?

整个过程,确实出现了好几处的迷惑现象,影响了他对问题的判断;下面就从一个小案例加上源码分析,来看看到底发生了什么。

问题复现

为了方便说明问题,这里用一个简单的业务场景来模拟一下;

数据表

一张简单的学生信息表

需求

需要按id顺序(order by id)获取出学号(student_id)对应的学生信息;为了方便业务层面根据学号获取数据,这位朋友采用了如下的数据格式,并用了HashMap在业务代码中接收数据:

{
   
   
	"S000001": {
   
   
		"name": "张三",
		"student_id": "S000001",
		"age": 7
	},
	"S000002": {
   
   
		"name": "李四",
		"student_id": "S000002",
		"age": 7
	},
	"S000003": {
   
   
		"name": "王五",
		"student_id": "S000003",
		"age": 8
	},
	"S000004": {
   
   
		"name": "赵六",
		"student_id": "S000004",
		"age": 8
	}
}

代码实现

  • Dao

    @MapKey("student_id")
    HashMap<String, Object> getStudentId();
    
  • xml

    <select id="getStudentMap" resultType="java.util.HashMap">
        select student_id , `name` , age
        from student_info
        order by id
    </select>
    
  • 测试用例

    @Autowired
    StudentInfoMapper studentInfoMapper;
    
    @Test
    void map() {
         
         
        HashMap<String, Object> studentId = studentInfoMapper.getStudentMap();
        studentId.forEach((id, studentInfo) -> log.info("学号:{} 信息:{}", id, JSON.toJSONString(studentInfo)));
    }
    

问题点

以上代码的执行日志;

当学号是如下数据再查询的时候,整个数据查询和使用都是没有任何问题

==>  Preparing: select student_id , `name` , age from student_info order by id
==> Parameters: 
<==    Columns: student_id, name, age
<==        Row: S000001, 张三, 7
<==        Row: S000002, 李四, 7
<==        Row: S000003, 王五, 8
<==        Row: S000004, 赵六, 8
<==      Total: 4
Closing non transactional SqlSession 
StudentTest    : 学号:S000001 信息:{
   
   "name":"张三","student_id":"S000001","age":7}
StudentTest    : 学号:S000002 信息:{
   
   "name":"李四","student_id":"S000002","age":7}
StudentTest    : 学号:S000003 信息:{
   
   "name":"王五","student_id":"S000003","age":8}
StudentTest    : 学号:S000004 信息:{
   
   "name":"赵六","student_id":"S000004","age":8}

但是当把学号换成以下数据之后:

根据查询结果和输出日志可以看到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一行Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值