HashMap源码解析

源码博客相关博客写了那么多,突然想起来都没有写一篇我们日常开发中最常见的HashMap,今天简单补一下!

HashMap简介:

HashMap 是应用更加广泛的哈希表实现,行为上大致上与 HashTable 一致,主要区别在于 HashMap 不是同步的,支持 null 键和值等。通常情况下,HashMap 进行 put 或者 get 操作,可以达到常数时间的性能,所以它是绝大部分利用键值对存取场景的首选,比如,实现一个用户 ID 和用户信息对应的运行时存储结构。


HashMap经验总结:

(1)HashMap基于哈希思想,实现对数据的读写。
(2)当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。
(3)当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。
(4)HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。
(5)HashMap在每个链表节点中储存键值对对象。当两个不同的键对象的hashcode相同时,它们会储存在同一个bucket位置的链表中,可通过键对象的equals()方法用来找到键值对。如果链表大小超过阈值(TREEIFY_THRESHOLD, 8),链表就会被改造为树形结构。


HashMap源码分析:

1、HashMap内存储的元素是Entry,并且Entry是按照链表的形式来存储的。

// 用数组来存储,它的原理是每个数组的元素都是一个链表头
transient Entry<K,V>[] table; 

Entry的定义如下:

static class Entry<K,V> implements Map.Entry<K,V> {

        final K key;
        V value;
        Entry<K,V> next;
        int hash;
}

2、HashMap的get(Object key)方法:

public V get(Object key) {

   // 对key进行判空
   if (key == null)
       return getForNullKey();
   // 根据key找Entry
   Entry<K,V> entry = getEntry(key);
   return null == entry ? null : entry.getValue();
}
final Entry<K,V> getEntry(Object 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;
         if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
             return e;
     }
     return null;

   }

3、 put(key,value)方法:

public V put(K key, V value) {

    // 对key进行判空处理
    if (key == null)
        return putForNullKey(value);

    // 计算hash值
    int hash = hash(key);

    // 查找在数据中的位置,然后沿着链表查找 ,如果有相同的值就覆盖,没有就加一个entry
    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;

  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值