理解HashMap源码

jdk1.7中的HashMap源码

1.函数签名

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable实行了Map接口。

2.静态内部类Entry,(jdk1.8中叫做Node,都表示节点的意思)
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

有四个关键点:hashkeyvaluenext

3.关键的成员变量

默认的初始容量:16

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

最大的容量

static final int MAXIMUM_CAPACITY = 1 << 30

默认的装填因子

static final float DEFAULT_LOAD_FACTOR = 0.75f;

阈值:最大的容量*装填因子
底层的Entry的一个数组的引用

transient Node<K,V>[] table;

Map中节点的个数

transient int size;
4构造方法

把默认的装填因子,赋值给loadFacto

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

在这里插入图片描述
这段代码中一直在进行位的的左移,是为了保证capacity(主数组的长度)的值永远为2的倍数,这与后面计算哈希码有关。
在这里插入图片描述

添加操作(put方法)

在这里插入图片描述
存储元素分为3步
(1)计算哈希码
在这里插入图片描述
这里调用了hash()方法,该方法中调用了hashcode()方法

,并且还进行了更加复杂的操作,目的就是为了,使计算出的哈希码不同。
(2)计算存储位置
在这里插入图片描述
这里使用的是位运算,目的就是为了提高效率。只有当哈希码的值是二的倍数是,才会让上面的结果与直接对length取模的结果相同。
(3)添加到链表中
在这里插入图片描述
如果size>=阈值,并且要添加的存储位置不为空,就会对table进行扩容,扩容为原来的二倍。最终都要创建一个新的节点。如果发现有相同的key就会用新的value替代旧的value,并且返回旧的value

在这里插入图片描述
并且会加到链表的头部。

get方法

找value的时候,其实就找的是Entry,因为Entry就包含value和key。
在这里插入图片描述
根据key找value
在这里插入图片描述

jdk1.8的变化

jdk1.8中依然是一个table,但如果链表中的节点个数>=8时,就会采用红黑树结构。来提高效率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值