Map.Entry接口如何在不创建对象的情况下调用getValue()/ getKey()方法?

时间:2018-02-25 09:09:51

标签: java collections hashmap

以下是该方案:

Set<Map.Entry<String,Integer>> st=hashMap.entrySet();
for(Map.Entry<String,Integer> me : set)
{
  System.out.println(me.getKey()+":"+me.getValue());
}

现在我的问题是,如果Set,Map,Entry都是接口,getKey()和getValue()是Entry接口内的方法,Map.Entry如何在不创建对象的情况下调用它们?

4 个答案:

答案 0 :(得分:1)

HashMap具有所有这些接口的内部实现。

例如,有一个EntrySet类,用作Set方法返回的entrySet()的实现:

public Set<Map.Entry<K,V>> entrySet() {
    Set<Map.Entry<K,V>> es;
    return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}

有几个类用作Map.Entry的实现。

例如:

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

答案 1 :(得分:1)

将我的公司扩展到答案:

基本思路是暴露界面隐藏实现。通常方法返回类型是接口,并且从方法的一侧返回隐藏实现。这使得这些代码(libs)的用户与实现分离。实现类可以在不受用户影响的情况下进行更改。

现在您的查询

Set<String,Integer> st=hashMap.entrySet();

HashMap源代码有一个实现Set的内部类。方法entrySet()存在于HashMap中,它返回该类的一个实现Set 的对象。签名中的返回类型是Set而不是实现类,但它是实现返回的Set接口的具体类的对象。

这样HashMap.java的作者就隐藏了你的实现。他们可以随意更改新版Java中的实现类。只有他们需要注意他们的新实现类实现Set接口。

类似于以下代码。

public interface InterfaceExposed{
      public void task();
} 

public class A{
     private class Implementation implements InterfaceExposed{
       public void task(){
             // some code to do task as per current implementation.
       }
     }
     public IExposedInterfaceOfA similarToEntrySet(){
          return new Implementation();
    }
} 

现在,A类用户将依赖于公开的接口,并且不会知道并且不依赖于隐藏的私有实现。

 A a = new A();
 IExposedInterfaceOfA xyz =    a.similarToEntrySet();
 xyz.task();

在这里,您可以看到xyz属于IExposedInterfaceOfA类型,但它引用了Concrete类实现的对象。

答案 2 :(得分:0)

SetEntry对象是在Hashmap类内部创建的。如果您看到java.util.Hashmap的源代码并访问entrySet()方法,您会看到它创建了一个具体的EntrySet(扩展了AbstractSet类,后者又实现了Set接口)对象。您引用的此对象为Set。同样,Hashmap提供了Entry类的内部实现,其中一个是Node,您将再次找到源代码。我强烈建议您访问源代码。

正如Linus Torvalds所说,

  

谈话很便宜,告诉我代码

答案 3 :(得分:0)

类结构超过继承。

entrySet方法的定义返回嵌套类EntrySet的对象。

EntrySet是实现Map.Entry接口的具体类。

Entry也是实现Map.Entry接口的具体类。 Entry类定义了getKeygetValue方法。

EntrySetEntry是HashMap类中组成的类。 因此,当实例化HashMap的对象时,可以使用这些方法。

HashMap source code