【问题标题】:why Map.Entry is not array? [closed]为什么 Map.Entry 不是数组? [关闭]
【发布时间】:2015-02-18 17:53:33
【问题描述】:

如果 Map.Entry 是 Map.Entry [] 而不是在 hashMap 中列出会发生什么?我只是想了解为什么bucket是列表而不是hashmap java中的数组实现。

【问题讨论】:

  • 每次向数组添加元素时都必须重新调整其大小。列表更加动态
  • 是不是唯一的原因,我的意思是从列表中查找元素必须去每个节点。
  • 除非官方文件在某处谈论这个设计决定,否则这个问题的答案将完全基于意见
  • 我这里没有 Java 8,但在 7 中,HashMap 中的数据 一个数组:transient Entry<K,V>[] table;
  • @azurefrog 数组中的每个条目实际上是/曾经是一个链表。该问题似乎询问有关此链接列表的问题。

标签: java arrays collections


【解决方案1】:

我认为您在谈论每个存储桶条目中的 LinkedList

假设它是一个数组,当您向该存储桶添加一个元素时,您必须创建一个一定大小的数组,例如 10,在这里您已经为 10 个条目分配内存(当然不是太多),但是该数组中的元素是根据具有相同hashcode() 但不同equals() 的元素添加的。 如果该桶中只有 2 个元素,但我们为 10 个保留了空间,您最终可能会得到稀疏填充的数组。

此外,只要您添加具有相同哈希码的元素,您就必须重新调整这些存储桶数组的大小。当您需要处理重新调整大小时,您通常会维护一个计数器来检查元素数量是否达到当前数组大小,创建一个更大的数组,复制所有这些元素,您必须将所有这些东西放在一个 @987654325 @调用Map :) 数组的主要优点是随机访问,但是当你尝试get数组中的某个元素时,它不知道哪个元素与equals()匹配,所以它会遍历所有元素该数组失去了数组的优势。

但如果您使用LinkedList,您只需继续添加元素,无需创建/重新调整数组大小。此外,如果您注意到,他们在向LinkedList 添加元素时正在做的一件聪明的事情是他们不会遍历整个列表来查找最后一个元素。他们创建了一个新的Entry 对象,其下一个元素指向存储在存储桶索引中的现有元素,并更新存储桶索引以指向这个新元素,这样他们就不必在每次添加新元素时遍历列表元素。所以这是内存和速度的提升:)

jdk8 中的另一个更新是,这个 LinkedList 实现在达到阈值 (8) 后更改为 Tree。这是为了促进更快的查找,因此不是在 O(n)(线性)时间内遍历所有元素到 get 某个元素,现在是 O(logn)

【讨论】:

  • 为了更好地理解HashMap的实现,阅读this
  • 值得注意的是,硬编码的单链表对于非常小的 n(例如 0、1 或 2)非常非常有效——这正是您对哈希表存储桶的期望。
  • 我同意这是稀疏数组和节省空间的论点。
【解决方案2】:

嗯,它会更难处理,例如重新调整大小。

如果您查看List 类的代码,您会发现在基础上,它们中的大多数只是Array,具有更易于开发人员处理数组的方法。

【讨论】:

  • 是的,我同意 List 实现,但 Map.Entry 有下一个指针,它将指向内存中的下一个位置,而不是连续的内存块
  • 并不是所有的列表都只是数组包装器......就像linkedlist一样
  • @Brijesh 下一个指针不指向内存中的下一个位置,它指向前一个Entry,它在您创建新时位于后备数组中的给定索引处Entry 用于该索引。
  • @azurefrog 据我了解,条目是数组对象,但在内部每个存储桶都可以拥有具有相同哈希码的对象列表,我的意思是说列表。所以它有指向下一个位置的指针。我的理解正确吗?
  • Entry 本身是一个单链表,它有 4 个属性 - 键、值、哈希码和一个 next 属性,它是另一个 Entry 对象,所以简单地说,HashMap 是一个链表数组:)
【解决方案3】:

下面提到的差异将帮助您理解为什么不Map.Entry[]

主要考虑是SIZE(第2点)但也有其他原因

列表(在这种情况下为链表)在以下情况下优于数组:

  1. 您需要从列表中进行恒定时间的插入/删除(例如 在实时计算中,时间可预测性是绝对的 关键)
  2. 您不知道列表中有多少项。用数组, 如果数组也增长,您可能需要重新声明和复制内存 大
  3. 您不需要随机访问任何元素

在以下情况下最好使用数组:

  1. 您需要对元素进行索引/随机访问

  2. 您提前知道数组中的元素数量,以便 您可以为数组分配正确的内存量

  3. 数组有 O(1) 次随机访问,但 真的很昂贵 添加 东西上或删除东西。

More Reasons are here , Please Help yourself

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 2013-04-01
    • 2011-09-25
    • 1970-01-01
    相关资源
    最近更新 更多