HashMap底层源码分析

在这里插入图片描述

HashMap底层源码分析

HashMap主要是用来存放键值对的,它基于哈希表的Map接口实现,是常用的Java集合之一,是非线程安全的。

HashMap可以存放null的Key和value,但是null作为键只能有一个,作为value可以有多个

方法名称说明
V put(K key, V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中键值对的个数

HashMap结构

HashMap内部方法

图标为m表示method

image-20240318161136018

HashMap内部类

图标为c表示class

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

HashMap内部属性

图标为f表示field

image-20240318161341292

static class Node<K,V> implements Map.Entry<K,V> {}

HashMap中每个元素都是一个Entry对象,

数组+链表+红黑树

// 表示数组默认的大小 为16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

// 表示默认的负载因子(加载因子)为0.75
// 当数组元素个数超过0.75*16=12的时候就进行扩容,扩容为原来的2倍空间大小
static final float DEFAULT_LOAD_FACTOR = 0.75f;

// 表示HashMap最大的空间为 1073741824
static final int MAXIMUM_CAPACITY = 1 << 30;

构造方法

public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

HashMap中的Hash值只与键有关系与值无关

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

// 返回键所对应的哈希值
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

>>> 表示无符号右移

扩容机制

调用空参构造的时候,只把属性loadFactor初始化为0.75

剩余的核心源码主要涉及到put操作:

  • 如果当前位置没有值,则直接在数组中添加该键值对,即Node对象
    • 如果数组长度超过其初始长度16*0.75=12的时候,则会进行扩容,扩容成原来的2倍
  • 如果当前位置有值,需要判断和当前新添加的键是否一致: PUT操作
    • 一致:
      • 则进行覆盖更新
    • 不一致:
      • 则在其后以链表的形式进行追加。
      • 当链表的长度达到8【TREEIFY_THRESHOLD】的时候,则会调用treeifyBin()方法,此方法会根据HashMap数组长度来判断是否需要转成红黑树。只有当数组长度大于或者等于64【MIN_TREEIFY_CAPACITY】的情况下,才会执行转换红黑树的操作,以减少搜索时间。否则就只执行resize()方法对数组进行扩容。

get操作:

判断hash和key是否相等,如果是就直接返回,如果不是,需要判断是否是红黑树,是的话按照红黑树的方式进行搜索;如果也不是红黑树就按照链表的顺序从前往后进行遍历查找。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值