• java-hashmap 工作原理


    HashMap有一个名为Entry类的内部类,其中包含键和值。还有一个叫做next的东西,你稍后就会知道。

     static class Entry<K,V> implements Map.Entry<K,V> 
     {
         final K key;
         V value;
         Entry<K,V> next;
         final int hash;
         ........
     }

    你应该知道HashMap将Entry实例存储在数组中,而不是作为键值对存储。为了存储值,都是使用HashMap的put()方法。让我们深入研究一下,看看它是如何工作的。

    Put()方法如何在内部工作?

    代码如下:

    public V put(K key, V value) 
    {
        if (key == null)
           return putForNullKey(value);
        int hash = hash(key.hashCode());
        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;
     }

    首先,它检查给定的密钥是否为null。如果给定键为null,则它将存储在零位置,因为null的Hashcode将为零。

    然后,通过调用hashcode方法将hashcode应用于键. hashcode()。为了获得数组范围内的值,将调用hash(key.hashCode()),它将对hashcode执行一些移位操作。

    indexFor()方法用于获取存储条目对象的确切位置。

    接下来是最重要的部分——如果两个不同的对象具有相同的hashcode(例如Aa和BB将具有相同的hashcode),那么它会存储在同一个bucket中吗?为了处理这个问题,让我们考虑数据结构中的LinkedList。它将有一个“next”属性,它总是指向下一个对象,就像条目类中的下一个属性指向下一个对象一样。使用具有相同hashcode的不同对象将彼此放置在一起。

    在发生冲突的情况下,HashMap将检查下一个属性的值。如果为空,则将条目对象插入该位置。如果下一个属性不为空,那么它将保持循环运行,直到下一个属性为空,然后将条目对象存储在那里。

    如何在HashMap中防止重复键?

    众所周知,HashMap不允许重复键,即使在插入具有不同值的相同键时,也只返回最新的值。

    LinkedList中的所有条目对象都有相同的hashcode,但HashMap使用equals()。这个方法检查相等性,因此如果key.equals(k)为真,它将替换Entry类中的值对象,而不是键。通过这种方式,它可以防止插入重复的键。

    Get()方法如何在内部工作?

    将使用put()方法中应用的几乎相同的逻辑来检索值。

    public V get(Object key) 
    {
        if (key == null)
           return getForNullKey();
         int hash = hash(key.hashCode());
         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.equals(k)))
                 return e.value;
         }
             return null;
     }

    首先,它获取传递的密匙对象的散列码,并查找bucket位置。

    • 如果找到了正确的bucket,它将返回该值。
    • 如果没有找到匹配,则返回null。
    • 如果两个键具有相同的Hashcode会发生什么?

    这里将使用相同的冲突解决机制。key.equals(k)将检查,直到它为真,如果为真,它将返回它的值。

    转载自 https://zhuanlan.zhihu.com/p/98883914

  • 相关阅读:
    map函数
    修改文件夹所有者权限
    [Python]Python基础趣讲精练
    jmeter生成随机字符串
    Jmeter生成8位不重复的随机数
    Jmeter接口测试使用总结
    Jmeter模拟多个号码注册
    Jmeter实现多用户注册登录
    jmeter 生成随机数(手机号)&随机中文字符
    python接口自动化如何封装获取常量的类
  • 原文地址:https://www.cnblogs.com/QicongLiang/p/13362227.html
Copyright © 2020-2023  润新知