Java 无法理解entrySet()方法

Java 无法理解entrySet()方法,java,hashmap,Java,Hashmap,我们可以使用entrySet()方法迭代存储在Node[]表字段中的hashmap键值对 HahMap<K,V> hashmap = new HashMap<>() ; public Set<Map.Entry<K,V>> entrySet() { Set<Map.Entry<K,V>> es; return (es = entrySet) == null ? (entrySet = new EntryS

我们可以使用entrySet()方法迭代存储在Node[]表字段中的hashmap键值对

HahMap<K,V> hashmap = new HashMap<>() ;

public Set<Map.Entry<K,V>> entrySet() 
{
    Set<Map.Entry<K,V>> es;
    return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
HahMap hashmap=newhashmap();
公共集入口集()
{
设置es;
return(es=entrySet)==null?(entrySet=newentryset()):es;
}
当我们在for each循环中使用此选项时,如:

for ( Map.Entry<K,V> entry : hashmap.entrySet () ) 
{
... 
// entry is an object of return type Map.Entry and object type Node . 
// got the object type by calling entry.getClass() and also no other inner class other than Node implements Map.Entry .   ; 

} 
for(Map.Entry:hashmap.entrySet())
{
... 
//条目是返回类型映射的对象。条目和对象类型节点。
//通过调用entry.getClass()获取对象类型,并且除了节点实现Map.entry之外,没有其他内部类;
} 
这些对象存储在一个集合中。但是将它们链接到具有键值对的字段表的代码在哪里呢

例如: 在toString()方法中,当我们使用iterator()方法获取Iterable,并对Iterable调用next()方法时,调用将转到HashIterator类的nextNode(),其中返回的对象链接到HashMap类的表字段。
但这里发生了什么?请帮忙

如果我没有遗漏您问题中的任何内容:
EntrySet
覆盖
iterator
方法(使其成为forEach中使用的
Iterable
),该方法反过来返回
EntryIterator
-它覆盖
下一个
方法:

public final Map.Entry<K,V> next() { return nextNode(); }
public final Map.Entry next(){return nextNode();}
但是它还扩展了定义
hasNext
方法的
HashIterator


其实就这么简单。但通常这些都是内部类,它们可以访问
HashMap
类中可能需要的所有内容

您似乎对视图缺乏理解。视图没有存储的数据,只是通过委托给实际的数据对象来实现某个接口

一个简单的例子是通过集合创建的列表视图。不可修改列表(…)
,它不包含任何数据,但将所有方法调用委托给原始列表,当然不包括修改方法

条目集通过委托给基础映射来实现
set
接口。最值得注意的是,通过返回一个
迭代器
,因为大多数方法都是建立在这个迭代器的基础上的,只有少数其他方法会被性能覆盖,例如
size()
直接委托给映射的
size()
。因此,如果条目集似乎包含某些内容,那么它就是,因为迭代器在遍历过程中报告它

Hashmap
的条目集迭代器迭代条目的内部数组,就像键集迭代器和值集合迭代器一样。它们之间唯一的区别是在
next()
方法中返回哪个对象,条目集迭代器只返回条目,其他两个分别提取键。条目的值。这就是为什么这些迭代器只覆盖单个方法

请注意,这种交互作用也可以反过来看。当您通过扩展实现
Map
时,
entrySet()
是您需要实现的唯一方法,所有其他Map方法都已通过委托给条目集实现。不过,为了提高性能,您可能会覆盖其中一些。但实际上包含数据的问题是没有意义的,
Map
和条目
Set
都是相同基础数据的视图

下面的示例可能会有所帮助:

String[][] pairs={ {"foo","bar"}, {"hello","world"} };

Map<String,String> map = new AbstractMap<String, String>() {
    public Set<Map.Entry<String, String>> entrySet() {
        return new AbstractSet<Entry<String, String>>() {
            public Iterator<Map.Entry<String, String>> iterator() {
                return Arrays.stream(pairs)
                    .<Entry<String,String>>map(p -> new SimpleImmutableEntry<>(p[0],p[1]))
                    .iterator();
            }
            public int size() {
                return pairs.length;
            }
        };
    }
};

System.out.println(map.get("foo"));
System.out.println(map.containsKey("hello"));
System.out.println(map.containsValue("world"));
map.forEach((k,v) -> System.out.println(k+" -> "+v));
System.out.println(map);
String[][]对={{{“foo”,“bar”},{“hello”,“world”};
Map Map=new AbstractMap(){
公共集入口集(){
返回新的AbstractSet(){
公共迭代器迭代器(){
返回数组.stream(对)
.map(p->newsimpleimutableentry(p[0],p[1]))
.iterator();
}
公共整数大小(){
返回对长度;
}
};
}
};
System.out.println(map.get(“foo”);
System.out.println(map.containsKey(“hello”);
System.out.println(map.containsValue(“世界”));
map.forEach((k,v)->System.out.println(k+“->”+v));
系统输出打印项次(map);

它创建了一个不可变的映射,而这个映射永远不会被放入。尽管如此,它还是通过所有
Map
方法报告了预期的内容,因为条目集迭代器报告了此内容。

EntrySet
HashMap
的一个内部类,它可以访问映射的所有值。请参见此处:我看不到所需的代码。
entrySet
是HashMap的类变量。
entrySet()
的代码是这样的:如果HashMap的entrySet为null,则返回new entrySet,否则返回HashMap的entrySet。向hashMap添加元素会调用
addEntry()
,这会将元素添加到hashMap的
entrySet
@Obenland,我的hashMap类中没有addEntry()方法。据我所知,在调用entrySet()时,Set entrySet的do元素是通过调用EntryMap类的迭代器()方法初始化的方法。@它们未初始化。。。它们已经在
地图中就位了
——唯一的问题是它们被迭代了。@steve我根本不明白你的意思。。。你能让我更清楚一点吗?我的意思是:我们在for循环中得到Set entrySet,然后我们一个接一个地得到这个集合的元素,但是要得到它们,必须首先使用put()方法插入它们,它们是如何插入的?@steve ok。。。现在这更令人困惑。它们显然是通过
put
方法插入的。考虑更简单,<代码>放置<代码>将条目放在一个数组中,而<>代码> EngyStuts只会重复该数组。我知道你有些不明白的事,但我不明白你到底想说什么?内部entrySet()方法:Set entrySet=new entrySet();返回入口集;然后调用entrySet.iterator().next(),这将迭代条目的内部数组。