【零基础学java】(HashMap源码解析--添加第一个元素)

前言:

Map集合的底层原理,源码解析

Cltr+F12 搜索

Cltr+B跟进

Cltr+Alt+左键,回到上一步

向上的箭头,表示该方法是重写后的

向后的箭头,表示该方法是来自哪个类或者哪个接口

解释:

HashMap
哈希值只跟键有关系,跟值没有一点关系
Node<K,V>\[\]table 哈希表结构中数组的名字
DEFAULT---INITIAL---CAPACITY 默认数组长度16
DEFAULT---LOAD---FACTOR默认加载因子为0.75

HashMap里面的每一个对象包含以下内容

链表中的键值对对象

包含:int hash //键的哈希值

finalK key //键

v value //值

Node<K,V>nex t //下一个节点的地址值

红黑树中的键值对对象

包含:int hash //键的哈希值

finalK key //键

v value //值

TreeNode<K,V>parent //父节点的地址值

TreeNode<K,V>left //左子节点的地址值

TreeNode<K,V>right//右子节点的地址值

boolean red 节点的颜色

数组里面的键值对对象需要分情况讨论

1.创建对象

HashMap<String,Integer> hm = new HashMap<>();

2.添加元素

hm.put("aaa" , 111);

hm.put("bbb" , 222);

hm.put("ccc" , 333);

hm.put("ddd" , 444);

hm.put("eee" , 555);

添加元素的时候至少考虑三种情况:
2.1数组位置为null
2.2数组位置不为null,键不重复,挂在下面形成链表或者红黑树
2.3数组位置不为null,键重复,元素覆盖

put方法的底层源码(添加第一个元素时)

参数一:键

参数二:值

返回值:被覆盖元素的值,如果没有覆盖,返回null

public V put(K key, V value) {

return putVal(hash(key), key, value, false, true);

}

第一个参数hash(key),利用键计算出对应的哈希值,再把哈希值进行一系列的额外处理

简单理解

//参数一:键的哈希值

//参数二:键

//参数三:值

//参数四:如果键重复了是否保留

true表示老元素的值保留,不会覆盖

false,表示老元素的值不保留,会进行覆盖

//参数五暂时不了解

static final int hash(Object key) {

int h;

return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

}

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {

//定义一个局部变量,用来记录哈希表中数组的地址值。

Node<K,V>\[\] tab;

//临时的第三方变量,用来记录键值对对象的地址值

Node<K,V> p;

//表示当前数组的长度

int n;

//表示索引

int i;

//把哈希表中数组的地址值,赋值给局部变量tab

tab = table;

if (tab == null || (n = tab.length) == 0){

//1.如果当前是第一次添加数据,底层会创建一个默认长度为16,加载因子为0.75的数组
//2.如果不是第一次添加数据,会看数组中的元素是否达到了扩容的条件
//如果没有达到扩容条件,底层不会做任何操作
//如果达到了扩容条件,底层会把数组扩容为原先的两倍,并把数据全部转移到新的哈希表中

tab = resize();

//表示把当前数组的长度赋值给n

n = tab.length;

}

//拿着数组的长度跟键的哈希值进行计算,计算出当前键值对对象,在数组中应存入的位置

i = (n - 1) & hash;//index

//获取数组中对应元素的数据

p = tabi;

if (p == null){

//底层会创建一个键值对对象,直接放到数组当中(第一个元素)

tabi = newNode(hash, key, value, null);

//threshold:记录的就是数组的长度 * 0.75,哈希表的扩容时机 16 * 0.75 = 12

if (++size > threshold){

resize();

}

//表示当前没有覆盖任何元素,返回null

return null;

相关推荐
xcl09254 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐6 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长6 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn6 小时前
Spring 注解使用详解
java·spring
一条小小yu7 小时前
Spring IoC的理解
java·后端·spring
落魄实习生7 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈7 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白9 小时前
核心功能(Service接口)
java·mybatis
乌暮9 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习