目录
一、前言
首先说下演示流程及设计思路。
JDK1.8版本以上,HashMap在存储数据时,数据格式有两周,一个是链表,一个是红黑树本篇就HashMap的数据存储结构到底怎样,进行模拟和还原。
二、模拟流程
1、效果图
链表结构
红黑树结构
以上是跟踪HashMap中的数据存储格式,真实还原底层数据存储结构。
2、源码解析
效果图已经展示链表和红黑树的数据存储结构,下面我们进行设计。
查看HashMap源码,HashMap中随着数据增多,会自行扩容,直到扩容到64位时会进行红黑树转换。
/**
* The smallest table capacity for which bins may be treeified.
* (Otherwise the table is resized if too many nodes in a bin.)
* Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
* between resizing and treeification thresholds.
*/
static final int MIN_TREEIFY_CAPACITY = 64;
3、设计思路
设计一个类,例如MyMap,分三种场景向HashMap中put数据
- 正常循环6次向HashMap中添加MyMap
- 重写MyMap里的hashCode()方法,返回固定值1,循环6次添加到HashMap中
- 重写MyMap里的hashCode()方法,返回固定值1,循环12次添加到HashMap中
模拟如下:
package com.zhufeng.test;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: ShowHashMapData
* @Description 还原hashmap数据存储格式
* @author 月夜烛峰
* @date 2022/8/30 13:33
*/
public class ShowHashMapData {
static Map<MyMap, String> map = new HashMap<MyMap, String>(8);
public static void main(String[] args) throws InterruptedException {
for (int i = 1; i < 6; i++) {
MyMap m = new MyMap();
map.put(m, "value-"+i);
}
System.out.println("======数据添加完成======");
//等待jmap导出dump数据
Thread.sleep(100*1000);
}
}
class MyMap{
// @Override
// public int hashCode() {
// return 1;
// }
//
// @Override
// public boolean equals(Object obj) {
// return false;
// }
}
4、代码模拟
4.1运行代码
运行以上代码,控制台打印数据添加完成时,导出dump数据
命令:jmap -dump:file=dump-0.hprof,format=b pid
找到运行的java的pid,导出后,通过jhat查看
命令:jhat dump-0.hprof
浏览器访问 localhost:7000
可通过浏览器访问dump解析的数据
这时,HashMap中存储的数据格式是这个样子
点击其中一个,比如第7个,看一看到数据信息
这里value-2就是我们put的value值,next不为空,代表当前链表中有下一个节点,可以继续点击,可以查看下一节点的信息。
4.2 修改hashcode
放开代码中注释的内容,重写了两个方法,一个时hashcode(),一个时equals()。
目的是每次返回的hashcode都设置为1,并且通过equals()方法告知JVM是不同的对象。
看下效果:
所有的对象都被归到了hashcode为1的链表中,此时对象类型为Node,这也就是文章开篇的图一链表结构。
4.3 红黑树生成
修改for循环次数:
for (int i = 1; i < 12; i++) {
MyMap m = new MyMap();
map.put(m, "value-"+i);
}
再次运行代码:
这里数组个数扩容为64个,节点类型也由Node变为TreeNode,点击查看对象信息
TreedNode继承Node,所以类信息中带有Node的属性,主要看left、parent、right三个节点,parent为null代表当前节点为根节点,点击链接跟踪,即可还原出开篇图二的红黑树数据结构。