首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法理解entrySet()方法

无法理解entrySet()方法
EN

Stack Overflow用户
提问于 2017-07-28 08:47:02
回答 2查看 1.4K关注 0票数 1

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

代码语言:javascript
复制
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循环中使用它时,如下所示:

代码语言:javascript
复制
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类的表字段。但这里发生了什么?请帮帮忙。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-28 17:12:22

你似乎对什么是观点缺乏理解。视图没有存储的数据,但是只是通过委托给实际的数据对象来实现特定的接口。

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

条目集通过委托给底层映射来实现Set接口。最值得注意的是,通过返回Iterator,因为大多数方法都是在此基础上构建的,因此只有少数其他方法被重写以提高性能,例如,直接将size()委托给映射的size()。所以,如果条目集看起来好像包含了什么,那就是它,因为迭代器在遍历过程中报告它。

Hashmap的条目集迭代器遍历条目的内部数组,就像键集迭代器和值收集迭代器一样。它们之间唯一的区别是在next()方法中返回哪个对象,条目集迭代器只返回条目,另外两个提取密钥resp。条目的值。这就是为什么这些迭代器只覆盖单个方法的原因。

请注意,这种交互也可以从另一个角度看到。当您通过扩展Map实现AbstractMap时,entrySet()是您需要实现的唯一方法,所有其他映射方法都已经通过委托到条目集来实现。不过,为了提高性能,您可能会重写其中的一些。但是实际包含数据的问题是没有意义的,Map和条目Set都是对相同的底层数据的视图。

也许下面的例子会有所帮助:

代码语言:javascript
复制
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方法报告预期的内容,仅仅是因为条目集迭代器报告了这个内容。

票数 2
EN

Stack Overflow用户

发布于 2017-07-28 12:21:27

如果我没有遗漏您问题中的任何内容:EntrySet重写iterator方法(使其成为要在forEach中使用的Iterable ),然后返回EntryIterator -它覆盖next方法:

代码语言:javascript
复制
public final Map.Entry<K,V> next() { return nextNode(); }

但是它也扩展了定义hasNext方法的hasNext

其实就是这么简单。但一般来说,这些都是内部类--它们可以访问HashMap类中可能需要的所有东西。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45368913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档