HashMap深度分析(基于jdk1.8)

本文深入探讨了HashMap的工作原理,包括其基于数组和链表的数据结构、hash函数、put和get方法的分析,以及何时使用红黑树。在HashMap满载75%时会触发resize,可能导致线程安全问题。CocurrentHashMap通过CAS和synchronized确保并发安全性,并在特定条件下转化为红黑树。
摘要由CSDN通过智能技术生成

 

HashMap 的简介

  • Hashmap是一个散列桶(bucket ),存储的一对一对的数据,形式是:key---value。
  • Hashmap采用的是数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改。
  • HashMap 线程不安全,所以 HashMap 很快。
  • HashMap 可以接受 null 键和值,而 Hashtable 则不能。

HashMap 的工作原理

在使用put(key,value)方法向map中插入值得时候,会优先调用hash()方法,参数为key,意思就是先获取key得hashcode,计算需要将该key放入的位置。这里关键点在于指出,HashMap 是在 bucket 中储存键对象和值对象,作为Map.Node 。下面可以了解一下Hashmap的实现:

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;
        }
    }

解释:Node是Hashmap类的一个静态内部类,实现了Map.Entry<K,V>接口。里面存放的key,value,hash这几个参数共同组成了hashmap的数组需要的参数,而next是组成链表的重要成员。他们共同组成了NODE这个对象,NODE对象共同组成了Hashmap 的主要结构。

注意:

● HashMap数组:transient Entry[] table

● 数组默认长度:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4=16

● 数组最大长度:static final int MAXIMUM_CAPACITY = 1 << 30=1073741824

● 默认加载因子:static final float DEFAULT_LOAD_FACTOR = 0.75f

● 扩容临界值:private int threshold;(threshold=capcity*loadFactor)

DEFAULT_INITIAL_CAPACITY 是数组默认的长度即16,MAXIMUM_CAPACITY 是数组最大的长度2的30次方,原因是2的31次方就超过Integer.MAX_VALUE(2147483647)了(也就是2^31-1),而数组的长度都必须是2的次方(原因稍后会解释),所以数组最大长度只能是2的30次方。

数组的长度为2的次方原因:比如我们向HashMap中存入了两个键值对entry1(key1=”abc”,value1=”ABC”)、entry2(key2=”def”,value1=”DEF”),假设key1对应的hash值为18,二进制为10010,假设key2对应的hash值为27,二进制为11011。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值