我的接口返回的数据顺序总是不固定
问题描述
====
- 我在开发突发奇想。将表头信息也给查出来一并返回给前端了。但是正因为这一举动却带来嘲讽。说我的接口顺序不对
问题定位
====
- 首先说明下这个问题是刚入行时遇到的。当时很是困惑,当然啦现在看来真的是贻笑大方了。
- 刚入行那会一直都是使用
Mybatis
框架实现数据的获取的。突然接到一个需求是要求将数据列按照一定顺序返回。前端直接按照我返回的顺序进行渲染。 - 刚接到需求觉得很简单,将数据依次写入就行了。关于具体需求我们就不深究了。下面梳理下当时发现问题及解决的一个过程吧。
- 上面是自己写的一个列子。结果很明显我们写入的顺序是
a
、d
、b
、c
、e
但是显示出来的顺序缺失a
、b
、c
、d
、e
。 - 后来网上翻阅了一下资料说
HashMap
是不会按照写入顺序排序的。HashMap
的key的排序是按照key的hash值进行排序的 - 最近翻看了下
HashMap
的源码了解了其内部的元素存储原理才明白这个道理。此时才知其所以然。
问题分析
====
- 下面我们向
HashMap
中添加如下元素 。 - 然后当我们map进行输出的时候是先横向遍历。当遇到有纵向数据是在纵向遍历。最终输出的顺序就是0、16、1、17、18、8
问题解决
====
- 后来我看了下具体的Map的实现类,突然看到一个
LinkedHashMap
, 当时不知道是个啥玩意但是看名字感觉像是HashMap
的升级版而且是链式的。感觉有点排序的感觉 - 当时为了解决问题就决定尝试一把。
- 结果是完美的。bug解决收工回家。对应刚入行的我还是很有成就感的。时隔多年现在又重新收拾了下自己的bug。 决定一探究竟为什么
LinkedHashMap
可以实现按照写入顺序排序。 - 通过结构图我们清楚看到他是
HashMap
的子类。所以他的存储结构和HashMap基本上是一样的。因为这里是Bug解析所以关于LinkedHashMap
源码的东西我就不深入研究了。最终我追踪到了是其内部linkNodeLast
这个方法使其具有写入顺序的特性。 - 在每次通过
HashMap
put进数据之后会将当前添加进来的数据和上次添加的node进行链表关联。这样就使其都在一条链上 - 我们上面添加的数据最终其内部一个结构图如下
- 当然内部会有一个默认的节点作为头结点。
总结
==
- 对待技术我们要持有严谨的态度。因为代码是死的。但是人是活的,在设计代码的时候开发者肯定会考虑到尽可能多的情况。
- 我们使用java就是站在巨人的肩膀上。我们只有理解其内部原理才能用的得心应手。
- 我们下回再见
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!