我们可以使用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;
}
当我们在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 . ;
}
这些对象存储在Set中。但是将代码链接到具有键值对的字段表的代码在哪里。
例如: 在toString()方法中,当我们使用iterator()方法获取Iterable,并在Iterable上调用next()方法时,调用转到HashIterator类的nextNode(),其中返回的对象链接到HashMap类的表字段。 但这里发生了什么?请帮忙 。
答案 0 :(得分:1)
您似乎缺乏对视图的理解。 视图没有存储的数据,只是通过委托给实际的数据对象来完成某个接口。
一个简单的例子是通过Collections.unmodifiableList(…)
创建的列表 view ,它不包含任何数据,但当然将所有方法调用委托给原始列表,不包括修改方法。 / p>
通过委托给底层地图,条目集满足Set
接口。最值得注意的是,通过返回Iterator
,因为大多数方法都建立在此基础之上,只有少数其他方法被覆盖以提高性能,例如: size()
直接委托地图size()
。因此,如果看起来好像条目集包含某些内容,那么它就是因为迭代器在遍历期间报告它。
Hashmap
的条目集迭代器遍历条目的内部数组,就像键集迭代器和值集合迭代器一样。它们之间唯一的区别是它们在next()
方法中返回的对象,条目集迭代器只返回条目,另外两个提取密钥resp。条目的价值。这就是为什么这些迭代器只覆盖那个单一的方法。
请注意,这种互动也可以反过来看。通过扩展AbstractMap
来实施Map
时,entrySet()
是您需要实现的唯一方法,所有其他地图方法都已通过委派方式实施入门集。但是,您可以覆盖其中一些以提高性能。但实际上包含数据的问题没有实际意义,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);
它创建了一个永不放入的不可变映射。它仍然通过所有Map
方法报告预期内容,只是因为条目集迭代器报告了这些内容。
答案 1 :(得分:0)
如果我没有遗漏您的问题中的任何内容:EntrySet
会覆盖iterator
方法(将其设为Iterable
以便在forEach中使用),然后返回EntryIterator
- 它会覆盖next
方法:
public final Map.Entry<K,V> next() { return nextNode(); }
但它也扩展了定义HashIterator
方法的hasNext
。
实际上就是这么简单。但通常这些是内部类 - 他们可以访问HashMap
类中可能需要的所有内容。