热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么HashMap的get方法有一个FOR循环?

如何解决《为什么HashMap的get方法有一个FOR循环?》经验,为你挑选了3个好方法。

我正在查看HashMapJava 7 中的源代码,我看到该put方法将检查是否已存在任何条目,如果它存在,那么它将用新值替换旧值.

    for (Entry 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;
        }
    }

所以,基本上它意味着给定密钥总是只有一个条目,我也通过调试看到了这一点,但如果我错了,那么请纠正我.

现在,由于给定键只有一个条目,为什么该get方法有FOR循环,因为它可以简单地直接返回值?

    for (Entry 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;
    }

我觉得上面的循环是不必要的.如果我错了,请帮助我理解.



1> Eran..:

table[indexFor(hash, table.length)]HashMap可能包含我们正在寻找的密钥的桶(如果它存在于其中Map).

但是,每个存储桶可能包含多个条目(具有相同hashCode()或不同的键的不同键hashCode()仍然映射到同一个存储桶),因此您必须迭代这些条目,直到找到您要查找的键.

由于每个桶中的预期条目数应该非常小,因此该循环仍然在预期O(1)时间内执行.


@pjj我从来没有说过给定密钥可以有多个条目.我说一个给定的桶可以有多个条目.
@pjj不同的密钥可以具有相同的哈希码值,因此最终在同一个桶中(根据密钥的哈希值选择桶)

2> 小智..:

如果你看到HashMap的get方法的内部工作.

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

首先,它获取传递的密钥对象的哈希码,并找到存储桶位置.

如果找到正确的存储桶,则返回值(e.value)

如果未找到匹配项,则返回null.

有时可能存在Hashcode冲突的可能性,并且为了解决此冲突,Hashmap使用equals(),然后将该元素存储到同一存储桶中的LinkedList中.

让我们举个例子:在此输入图像描述

获取密钥vaibahv的数据:map.get(new Key("vaibhav"));

脚步:

    计算Key {"vaibhav"}的哈希码.它将生成为118.

    使用索引方法计算索引将为6.

    转到数组的索引6并将第一个元素的键与给定键进行比较.如果两者都是等于则返回值,否则检查下一个元素是否存在.

    在我们的例子中,它不是第一个元素,节点对象的下一个不是null.

    如果node的下一个为null,则返回null.

    如果node的下一个非空遍历到第二个元素并重复进程3,直到找不到key或next不为null.

对于此检索过程,将使用循环.有关更多参考,请参阅 此内容


请不要将JPG用于非摄影图像.
@pjj不一样*key*,但是相同的*hash*(或相同的数组索引,即使不是相同的哈希).这里答案的要点是`HashMap`不会(**不能**)神奇地包含一个独特的地方来放置将来"放入"的每个条目.被置于`HashMap`中的键可能具有*hash-conflicts*,在这些键中,即使它们不是真正相同的键,它们也希望放在结构中的相同位置.当条目"放入"地图时,有一种特殊的方法可以解决这个问题.在`get`上,你必须考虑到这一点.

3> Eugene..:

对于记录,在java-8中,这也存在(有点,因为还有TreeNode):

if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }

基本上(对于bin不是a的情况Tree),迭代整个bin,直到找到我们要查找的条目.

看看这个实现,你可能会理解为什么提供一个好的哈希是好的 - 所以不是所有的条目都在同一个桶中,所以有更大的时间来搜索它.


推荐阅读
  • 转载自:http:www.blogjava.netCarpenterLeearchive20160427430268.html总体介绍之所以把HashSet和HashMa ... [详细]
  • 标题: ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • HashMap:键值对(key-value):通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.默认是1:1关系:存在则覆盖,当key已经存在,则利用新的va ... [详细]
  • 单线程化的ConcurrentHashMap的性能要比同步的HashMap的性能稍好一些,而且在并发应用中,这种作用就十分明显了。ConcurrentHashMap的实现,假定大多数常用的操 ... [详细]
  • 我有3个来自RESEARCHS的映射值,指定要使用参考数据集填充的行中的范围。该研究 ... [详细]
  • 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每 ... [详细]
  • 本篇文章给大家分享的是有关Java中怎么对HashMap按键值排序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话 ... [详细]
  • ***功能:排序*privatestaticvoidoutputRegionStatistics(HashMap<String,Integer>regionMap){ ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 查找给定字符串的所有不同回文子字符串原文:https://www ... [详细]
author-avatar
华华eva3
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有