当前位置: 首页 > 知识库问答 >
问题:

如果Key的哈希码相同但等于方法return false,HashMap如何检索不同的值

阚吕恭
2023-03-14

我无法理解HashMap的工作模式。请帮助理解它。

假设我们有两个对象Obj1和Obj2,它们的Hashcode都是1212。现在,当我们运行“==”和equals时,它返回false。

现在我使用ValueObj1和Valueobj2作为HashMap中的值,分别具有键Obj2和Obj3。我相信这两个值将保存在与List相同的桶中。

我的问题是HashMap如何为Obj2选择Valueobj2,为Obj选择ValueObj1。假设有n.个这样的对象和值。这把钥匙--

假设两个条件都等于不被覆盖和被覆盖。

共有3个答案

汪文光
2023-03-14

< code>HashMap的工作原理是根据键的哈希值将其内容划分为多个桶。每个桶又包含一个条目列表,一个条目由键和值组成。

假设我们想在映射中查找x。我们计算x.hashCode()并选择适当的存储桶。然后我们遍历存储桶的列表并选择条目e,其中e.key等于x。然后我们返回e.value

代码

class Map {
    class Entry {
        Object key, value;
    }

    List<List<Entry>> buckets;

    Object get(Object key) {
        List<Entry> bucket = buckets.get(key.hashCode() % buckets.size());
        for (Entry entry : bucket) {
            if (Object.equals(key, entry.key) return entry.value;
        }
        return null;
    }
}

(免责声明:使用%来计算桶指数是一种过于简单的方法,不能按原样工作;它只是为了传达总体思想。)

彭飞虎
2023-03-14

您可以随时查看代码。

 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;
 }
  1. 所以它首先获取给定密钥的哈希值。
  2. 使用该哈希它定位表(在其他答案中称为桶)。
  3. 对于存储桶中的每个条目,它会测试键是否等于表条目键,如果是,它会找到正确的项目。

使用< code>equals比较,将关键字按散列划分到桶中减少了线性搜索的规模。所以你可以看到为hashcode返回一个固定值是多么有害。关于良好的hashcode计算技巧,请参见此处。

夏烨霖
2023-03-14

一个< code > HashMap /< code > HashSet 为每个桶实现一个键列表(在< code>Map的情况下连同值一起)。如果多个键共享同一个< code>hashCode值,它们将被放在这个列表中。

因此,搜索方法首先提取查询关键字的<code>hashCode</code>,然后遍历相应的列表,直到<code>等于</code>方法成功。在<code>HashSet</code>的情况下,这意味着找到了<code>键</code>;在<code<HashMap</code>的情况中,它返回元组的另一端:值。

因此,HashMap 的内存工作原理如下:

+--------+--------+--------+--------+
|   00   |   01   |   10   |   11   |
+--------+--------+--------+--------+
    |        |        |        |
 k00/v00     _     k06/v06     _
    |                 |
 k08/v08           k14/v14
    |                 |
 k04/v04              _
    |
    _

你看到的是在四个桶的上面。每个桶都有一个列表(下面的项目),存储键(< code>k)和值(< code>v)的元组。因为这里只有四个桶,散列算法使用模4运算,所以具有值< code>v06的关键字< code>k06将被放入桶< code>06 mod 4 = 02中,因此< code>10。如果第二个键< code>k14添加了< code>14 mod 4 = 02,即< code>10,则只需将其添加到列表中。

由于值也与它一起存储,因此可以执行快速查找操作。因此,密钥与值一起存储。

您注意到,遍历(链接)列表是一项昂贵的操作。但<code>HashMap</code>的意义在于,人们希望使用正确术语(共享同一存储桶的密钥数)的哈希冲突次数非常少。一般来说,每个桶可能需要两到三个元素。因此,通过在恒定时间内选择正确的bucket来实现性能提升,搜索bucket需要线性时间(或者,如果键的顺序完整,可以实现(平衡)二叉树以在对数时间内搜索)。然而,最糟糕的情况是,<code>HashMap</code>可以实现与<code>ArrayList</code>/<code>LinkedList</code>条目相同的性能,但考虑到哈希函数的设计得体,概率非常低。

 类似资料:
  • 问题内容: 根据我的理解,我认为: 两个对象具有相同的哈希码是完全合法的。 如果两个对象相等(使用equals()方法),则它们具有相同的哈希码。 如果两个对象不相等,则它们不能具有相同的哈希码 我对么? 现在,如果正确的话,我有以下问题:HashMap内部使用对象的哈希码。因此,如果两个对象可以具有相同的哈希码,那么如何HashMap跟踪它使用的键? 有人可以解释HashMap内部如何使用对象的

  • 问题内容: Hashcode()和equals()的概念是 1)如果两个对象根据equal()相等,则在这两个对象中的每一个上调用hashcode方法应产生相同的哈希码。 另一个是 2)如果两个对象根据equal()不相等,则不需要在两个对象中的每一个上调用hashcode方法必须产生不同的值。 我尝试并理解了第一个,这是第一点的代码。 上面的程序为两个不同的对象提供了相同的哈希码。 有人可以用一

  • 问题内容: 我有一个dynamodb表来存储电子邮件属性信息。我在电子邮件上有一个哈希键,在时间戳(数字)上有范围键。使用电子邮件作为哈希键的最初想法是按电子邮件查询所有电子邮件。但是我想做的一件事是检索所有电子邮件ID(在哈希键中)。我为此使用了boto,但不确定如何检索不同的电子邮件ID。 我当前提取10,000条电子邮件记录的代码是 但是要检索不同的记录,我将必须进行全表扫描,然后在代码中选

  • 当人们说Hashmap比列表更快时,我对Hashmap或Hashtable的概念更困惑。我很清楚散列的概念,其中的值存储在给定密钥的散列代码中。 但是,当我想检索数据时,例如,它是如何工作的,我在一个HashMap中存储n个带有n个不同键的字符串。如果我想检索与特定键关联的特定值,它将如何在O(1)的时间内返回它?因为散列密钥将与所有其他密钥进行比较,对吗?

  • 据我所知,两个不相等的对象可以具有相同的哈希代码。当添加或从HashMap java中检索时,将如何处理这个问题?

  • 我会从我想达到的目标开始 意图 该软件在for循环中解析XML数据。处理数据的 for 循环将持续到 50(因为我得到了 50 个不同的结果)。我最初所做的是,-方法解析整个XML数据并将其保存到TextViews中并显示它。但现在我想添加一个启动画面,只要数据加载就会显示。 XML文件像任何其他普通XML文件一样构建,因此当我通过for循环时,键总是相同的,但值不同。 方法 我已经做的是创建一个