打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
java源码阅读笔记
1 HashMap方法
1.1 源码结构
//哈希桶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;    }    public final K getKey()        { return key; }    public final V getValue()      { return value; }    public final String toString() { return key + "=" + value; }    public final int hashCode() { //异域,相同为0不同为1.如果两个数值异或后的值相同,异或前可能不同。        return Objects.hashCode(key) ^ Objects.hashCode(value);    }    public final V setValue(V newValue) {        V oldValue = value;        value = newValue;        return oldValue;    }    public final boolean equals(Object o) {        if (o == this)            return true;        if (o instanceof Map.Entry) {            Map.Entry<?,?> e = (Map.Entry<?,?>)o; //值比较            if (Objects.equals(key, e.getKey()) &&                Objects.equals(value, e.getValue()))                return true;        }        return false;    }}public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b));}
JDK 1.8 添加红黑树是因为一旦链表过长,会严重影响 HashMap 的性能,而红黑树具有快速增删改查的特点。
1.2 查询、新增和数据扩容源码
1.2.1 查询
哈希冲突时需要通过判断 key 值是否相等,才能确认此元素是不是我们想要的元素
public V get(Object key) {    Node<K,V> e;    // 对 key 进行哈希操作    return (e = getNode(hash(key), key)) == null ? null : e.value;}final Node<K,V> getNode(int hash, Object key) {    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;    // 非空判断    if ((tab = table) != null && (n = tab.length) > 0 && //根据node数组的length和hash值获取此hash在map中的node        (first = tab[(n - 1) & hash]) != null) {        // 判断第一个元素是否是要查询的元素        if (first.hash == hash && // always check first node            ((k = first.key) == key || (key != null && key.equals(k))))            return first;        // 下一个节点非空判断        if ((e = first.next) != null) {            // 如果第一节点是树结构,则使用 getTreeNode 直接获取相应的数据            if (first instanceof TreeNode)                return ((TreeNode<K,V>)first).getTreeNode(hash, key);            do { // 非树结构,循环节点判断                // hash 相等并且 key 相同,则返回此节点                if (e.hash == hash &&                    ((k = e.key) == key || (key != null && key.equals(k))))                    return e;            } while ((e = e.next) != null);        }    }    return null;}1.2.2 新增
public V put(K key, V value) {    // 对 key 进行哈希操作    return putVal(hash(key), key, value, false, true);}语言方法
7839ak3J3
HWST1抖音容易上热门的句子「揭秘」请勿外传
90932010-10-01 10:33:53
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,               boolean evict) {    Node<K,V>[] tab; Node<K,V> p; int n, i;    // 哈希表为空则创建表    if ((tab = table) == null || (n = tab.length) == 0)        n = (tab = resize()).length;    // 根据 key 的哈希值计算出要插入的数组索引 i    if ((p = tab[i = (n - 1) & hash]) == null)        // 如果 table[i] 等于 null,则直接插入        tab[i] = newNode(hash, key, value, null);    else {        Node<K,V> e; K k;        // 如果 key 已经存在了,直接覆盖 value        if (p.hash == hash &&            ((k = p.key) == key || (key != null && key.equals(k))))            e = p;        // 如果 key 不存在,判断是否为红黑树        else if (p instanceof TreeNode)            // 红黑树直接插入键值对            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);        else {            // 为链表结构,循环准备插入            for (int binCount = 0; ; ++binCount) {                // 下一个元素为空时                if ((e = p.next) == null) {                    p.next = newNode(hash, key, value, null);                    // 转换为红黑树进行处理                    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                        treeifyBin(tab, hash);                    break;                }                //  key 已经存在直接覆盖 value                if (e.hash == hash &&                    ((k = e.key) == key || (key != null && key.equals(k))))                    break;                p = e;            }        }        if (e != null) { // existing mapping for key            V oldValue = e.value;            if (!onlyIfAbsent || oldValue == null)                e.value = value;            afterNodeAccess(e);            return oldValue;        }    }    ++modCount;    // 超过最大容量,扩容    if (++size > threshold)        resize();    afterNodeInsertion(evict);    return null;}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
HashMap底层原理实现源码探索(碰撞问题如何解决)
Java 数组到 HashMap 之算法解释
HashMap深入理解
Java Jdk1
【老实李】JDK1.8中HashMap的红黑树
看了这篇,HashMap底层原理终于搞懂了!
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服