阿里架构师教你如何十分钟深入理解HashMap源码

本文详细介绍了HashMap的桶结构、节点类型、put和remove方法的实现,以及rehash过程。文章通过分析HashMap的源码,揭示了其内部如何处理哈希冲突,何时会将链表转化为红黑树,以及如何进行扩容操作。通过对这些核心概念的探讨,帮助读者深入理解HashMap的工作原理。
摘要由CSDN通过智能技术生成

十分钟就要深入理解HashMap源码,看完你能懂?我觉得得再多看一分钟,才能完全掌握!

[外链图片转存失败(img-C72neM5a-1568723061512)(https://upload-images.jianshu.io/upload_images/16826084-eccd9643ad48ebf2.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

终于来到比较复杂的HashMap,由于内部的变量,内部类,方法都比较多,没法像ArrayList那样直接平铺开来说,因此准备从几个具体的角度来切入。

桶结构

HashMap的每个存储位置,又叫做一个桶,当一个Key&Value进入map的时候,依据它的hash值分配一个桶来存储。

看一下桶的定义:table就是所谓的桶结构,说白了就是一个节点数组。

transient Node<K,V>[] table;
transient int size;

节点

HashMap是一个map结构,它不同于Collection结构,不是存储单个对象,而是存储键值对。
因此内部最基本的存储单元是节点:Node。

节点的定义如下:

class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;
}

可见节点除了存储key,vaue,hash三个值之外,还有一个next指针,这样一样,多个Node可以形成一个单向列表。这是解决hash冲突的一种方式,如果多个节点被分配到同一个桶,可以组成一个链表。

HashMap内部还有另一种节点类型,叫做TreeNode:

class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
    TreeNode<K,V> parent;  // red-black tree links
    TreeNode<K,V> left;
    TreeNode<K,V> right;
    TreeNode<K,V> prev;    // needed to unlink next upon deletion
    boolean red;
 }

TreeNode是从Node继承的,它可以组成一棵红黑树。为什么还有这个东东呢?上面说过,如果节点的被哈希到同一个桶,那么可能导致链表特别长,这样一来访问效率就会急剧下降。 此时如果key是可比较的(实现了Comparable接口),HashMap就将这个链表转成一棵平衡二叉树,来挽回一些效率。在实际使用中,我们期望这种现象永远不要发生。

有了这个知识,就可以看看HashMap几个相关常量定义了:

static final int TREEIFY_THRESHOLD = 8;
static final int UNTREEIFY_THRESHOLD = 6;
static final int MIN_TREEIFY_CAPACITY = 64;
  • TREEIFY_THRESHOLD,当某个桶里面的节点数达到这个数量,链表可转换成树;
  • UNTREEIFY_THRESHOLD,当某个桶里面数低于这数量,树转换回链表;
  • MIN_TREEIFY_CAPACITY,如果桶数量低于这个数,那么优先扩充桶的数量,而不是将链表转换成树;

put方法:Key&Value

插入接口:

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}
final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

put方法调用了私有方法putVal,不过值得注意的是,key的hash值不是直接用的hashCode,最终的hash=(hashCode右移16)^ hashCode。

在将

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值