我们可以使用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 . ;
} 这些对象存储在一个集合中。但是,将它们链接到具有键值对的字段表的代码在哪里。
例如:在toString()方法中,当我们使用iterator()方法获得Iterable,并在Iterable上调用next()方法时,调用转到HashIterator类的nextNode(),其中返回的对象被链接到HashMap类的表字段。但这里发生了什么?请帮帮忙。
发布于 2017-07-28 17:12:22
你似乎对什么是观点缺乏理解。视图没有存储的数据,但是只是通过委托给实际的数据对象来实现特定的接口。
一个简单的例子是通过Collections.unmodifiableList(…)创建的列表视图,它不包含任何数据,但将所有方法调用委托给原始列表,当然不包括修改方法。
条目集通过委托给底层映射来实现Set接口。最值得注意的是,通过返回Iterator,因为大多数方法都是在此基础上构建的,因此只有少数其他方法被重写以提高性能,例如,直接将size()委托给映射的size()。所以,如果条目集看起来好像包含了什么,那就是它,因为迭代器在遍历过程中报告它。
Hashmap的条目集迭代器遍历条目的内部数组,就像键集迭代器和值收集迭代器一样。它们之间唯一的区别是在next()方法中返回哪个对象,条目集迭代器只返回条目,另外两个提取密钥resp。条目的值。这就是为什么这些迭代器只覆盖单个方法的原因。
请注意,这种交互也可以从另一个角度看到。当您通过扩展Map实现AbstractMap时,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方法报告预期的内容,仅仅是因为条目集迭代器报告了这个内容。
发布于 2017-07-28 12:21:27
如果我没有遗漏您问题中的任何内容:EntrySet重写iterator方法(使其成为要在forEach中使用的Iterable ),然后返回EntryIterator -它覆盖next方法:
public final Map.Entry<K,V> next() { return nextNode(); }但是它也扩展了定义hasNext方法的hasNext。
其实就是这么简单。但一般来说,这些都是内部类--它们可以访问HashMap类中可能需要的所有东西。
https://stackoverflow.com/questions/45368913
复制相似问题