【问题标题】:How is Map.Entry used in HashMap implementation?Map.Entry 在 HashMap 实现中是如何使用的?
【发布时间】:2020-07-29 04:03:51
【问题描述】:

我有一个问题,Map.Entry 如何在 Map 实现中使用,例如 HashMap。下面是HashMapjdk8中实现的代码,

public interface Map<K, V> {
    interface Entry<K, V> {
        ...
    }
}

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {

    static class Node<K,V> implements Map.Entry<K,V> {
        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
    }

    transient Node<K,V>[] table;

}

我有 2 个问题。

  1. 根据javadocMap.Entrypublic static interface,如public static interface Map.Entry&lt;K,V&gt;。为什么上面的interface Entry&lt;K, V&gt; 中缺少static? javadoc 是否仅指 Oracle jdk?

  2. 关于static关键字,我的理解是内部Map.Entry对象,table的元素类型,没有引用HashMap,因为Nodestatic类。 table 变量是 static 吗?如果tablestatic,那么所有HashMap 类对象将共享相同的table;这听起来不对。不是每个HashMap 对象都有不同的内存存储来托管它们的内容吗?

【问题讨论】:

  • 1.所有接口都是静态的。 2. table 变量不是静态的,正如您自己的代码摘录所示。 Map.Entry 对象只需要它们的键和值引用,而不需要对HashMap 的引用。你对这一点的推理不清楚。

标签: java interface static hashmap


【解决方案1】:

为什么上面的interface Entry&lt;K, V&gt; 中缺少static

来自JLS

9.5。成员类型声明

接口中的成员类型声明隐式为publicstatic。允许冗余指定这些修饰符中的一个或两个。

关于static关键字,我的理解是内部Map.Entry对象,table的元素类型,没有对HashMap的引用,因为Node是一个static类。

它没有参考,因为它不需要参考。您需要阅读散列映射数据结构以了解其工作原理。如果您要问Node 是否可以引用到地图,那么是的,如果它传递给它(通过构造函数或方法)。如果您问Node 可以访问封闭的地图,那么不,因为正如您所说,Node 是静态的。如果你尝试做类似的事情,你会得到的错误

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

    HashMap<K,V> map = HashMap.this;
}

No enclosing instance of the type HashMap is accessible in scope。如果Node 不是static,则代码将编译。

表变量是static吗?

不,是transient,也就是说不会通过Serializable接口的协议进行序列化。

不是每个HashMap 对象都有不同的内存存储来托管它们的内容吗?

是的,这就是 tableentrySetkeySetvalues(后两个在超类中)等内容的存储位置。

【讨论】:

  • 感谢@user1803551 1. 由于表是非静态成员,每个表对象都包含对其外部类HashMap 的隐式引用。 2. table的元素是Node。由于 Node 是静态类成员,因此每个表的元素不包含对其外部类 HashMap 的引用。如果所有 Node 对象都是静态的,那么它们本质上是由所有 HashMap 对象共享的。这很奇怪,因为 Node 对象是可变的(通过 Map.Entry 的 setValue() 方法)。如果一个 HashMap 对象修改了一个 Node 对象,另一个 HashMap 对象可以看到更改。不违反封装原则吗?
  • @sofabc 如果所有 Node 对象都是静态的,那么它们本质上是由所有 HashMap 对象共享的 不,类是staticstatic 不适用于该类的实例。 如果一个 HashMap 对象修改了一个 Node 对象,那么另一个 HashMap 对象可以看到变化。不是因为上面的。
  • @user1803551,你正中了它的头。节点类是静态的;和 Node 对象是非静态的。静态类类型仍然赋予 Node 对象一些特殊性。每个 Node 对象并不隐式包含对其外部类 HashMap 的引用。非常感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多