jdk7关于HashMap数据存储与获取的源码解析

一、存储数据解析
1、先看put方法

 public V put(K key, V value) {
     //如果key值为空,调用putForNullKey方法存储键值对,点进该方法中,可以看到,调用的addEntry方法默认会将内容存到数字下表为0的链表下
     if (key == null)
         return putForNullKey(value);
     //根据key计算并获取hash值
     int hash = hash(key);
     //根据hash值与链表长度获取所存数据应存放的数组下标
     int i = indexFor(hash, table.length);  
     //如果该下标在数组中已经存在数据,那么就会循环遍历链表下的数据
     for (Entry<K,V> e = table[i]; e != null; e = e.next) {
         Object k;
         //解决hash冲突,如果链表中的key值一样,则新的value值会覆盖原来的oldValue值
         if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
             V oldValue = e.value;
             e.value = value;
             e.recordAccess(this);
             return oldValue;
         }
     }
 
     modCount++;
     //如果,存在hash冲突,且链表中的key没有重复,那么就新增一个entry在该链表上
     addEntry(hash, key, value, i);
     return null;
 }

2、addEntry方法

void addEntry(int hash, K key, V value, int bucketIndex) {
    //如果集合存储长度>=(容量*负载因子 16*0.75,因为数组初始值为16,所以threshold初始值为12)且当前下标对应的值不为空,则需要扩容
    if ((size >= threshold) && (null != table[bucketIndex])) {
        resize(2 * table.length);
        hash = (null != key) ? hash(key) : 0;
        bucketIndex = indexFor(hash, table.length);
    }
    //继续创建entry值
    createEntry(hash, key, value, bucketIndex);
}

3、createEntry方法

void createEntry(int hash, K key, V value, int bucketIndex) {
     //将旧的链表赋值给entry的next,即extry的next地址指向之前的链表
     Entry<K,V> e = table[bucketIndex];
     //把之前的链表接到当前要存储的entry后面
     table[bucketIndex] = new Entry<>(hash, key, value, e);
     size++;
}

二、获取Map中数据
1、先看get方法

public V get(Object key) {
    //如果key值为空,直接通过getForNullKey方法获取value值
    if (key == null)
        return getForNullKey();
    Entry<K,V> entry = getEntry(key);
    //如果获取到的entry不为空,这返回该entry的value值
    return null == entry ? null : entry.getValue();
}

2、getEntry方法

final Entry<K,V> getEntry(Object key) {
    //获取key的hash值
    int hash = (key == null) ? 0 : hash(key);
    //如果通过hash值与数组长度计算的下标存在链表,且不为空,则遍历该链表
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
         e != null;
         e = e.next) {
        Object k;
        //如果hash值与key都相等的话,则返回entry值
        if (e.hash == hash &&
            ((k = e.key) == key || (key != null && key.equals(k))))
            return e;
    }
    //都找不到,自然返回空了
    return null;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值