HashMap底层原理详解

HashMap数据结构——数组+链表

在这里插入图片描述
Node[]是HashMap的核心数组结构,也称之为“位桶数组“,长度默认是16
在这里插入图片描述
Node的源码:

 /**
     * Basic hash bin node, used for most entries.  (See below for
     * TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
     */
    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() {
            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;
        }
    }

在这里插入图片描述
在这里插入图片描述

存储数据过程put(key,value)

在这里插入图片描述

  • hashcode是一个整数,需要将它转化成[0,数组长度-1]的范围。要求转换后的值尽量均匀分布在[0,数组长度-1]这个区间,减少"hash冲突"。
  • 散列算法:均匀分布,充分利用数组的寻址快的特点
    常见算法:相除取余——hash=hashcode%数组长度,这种算法可以让hash值均匀的分布在[0,数组长度-1]的区间。早期的HashTable就是采用的这种算法。但是这种算法由于使用了“除法”,效率低下。后来JDK改进了算法,首先约定数组的长度必须是2的整数幂,这样采用位运算即可实现取余的效果:hash=hashcode&(数组长度-1)
package cn.GTMStudion.collection;

public class TestMyHash {
    public static void main(String[] args) {
        int h=98989778;
        int length=16;
        myHash(h,length);
    }

    /**
     *
     * @param h 任意整数
     * @param length 长度必须为2的整数次幂,则h&(length-1)相当于对length取模
     * @return
     */
    public static int myHash(int h,int length){
        System.out.println(h&length-1);
        //length为2的整数幂情况下,和取余的值一样
        System.out.println(h%length);//取余数
        return h&(length-1);
    }
}  

在这里插入图片描述
在这里插入图片描述

取数据过程get(key)

在这里插入图片描述

扩容问题

在这里插入图片描述

JDK8中当链表的长度大于情况下变为红黑二叉树

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值