Java之HashMap学习

本文详细介绍了HashMap的工作原理,包括其内部结构、存储方式、扩容机制及与Hashtable的主要区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap是Hashtable的轻量级的实现,采用数据结构中的哈希表进行存储,遇到冲突时,采用拉链法解决冲突。

HashMap中有一个Entry[capacity]数组,Entry即为map中一个存储类,其中有成员key,value,next,next指向下一个同义词的Entry。

几个关键的属性

存储数据的数组

transient Entry[] table; 
默认容量

static final int DEFAULT_INITIAL_CAPACITY = 16;

最大容量

 static final int MAXIMUM_CAPACITY = 1 << 30;

默认加载因子,加载因子是一个比例,当HashMap的数据大小>=容量*加载因子时,HashMap会将容量扩容

static final float DEFAULT_LOAD_FACTOR = 0.75f;

当实际数据大小超过threshold时,HashMap会将容量扩容,threshold=容量*加载因子

int threshold;

加载因子

final float loadFactor;

寻址时,采用key的哈希值(通过一种算法对其hash值进行了运算)model table表的长度,得到相应的值。

插入时,在哈希表中遍历此值对应的链表,如果有相同的key值则替换其value值,如果没有则插入在表头。

    public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }


        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }


    indexFor方法,其中table的length初始值为16,最大值为1<<30(2^29),而table的容量扩充是通过左移来实现的,所以h&(length-1)相当于mod length

    static int indexFor(int h, int length) {
        return h & (length-1);
    }


如put代码所示,当hashmap中有此key时,替换掉原来的value,如果没有此key,则添加此Key,调用addEntry(hash,key,value,i)

    void addEntry(int hash, K key, V value, int bucketIndex) {
        //数量大于装载因子,进行扩容
        if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }

        createEntry(hash, key, value, bucketIndex);
    }

//往table中添加此key,相当于在链表表头插入该元素。(new Entry<>(hash,key,value,e) e参数为next)  
void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        size++;
    }



HashMap与Hashtable主要的区别在于,HashMap允许空(null)键值(key)和空value值,Hashtable是线程安全的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值