HashMap 的 entrySet 生成过程

XuanrenLu 2017-04-20 09:15:21
原来以为entrySet是随着put操作一块更新的,后来发现是调用entrySet()方法时才生成,但是在调试的时候,竟然没发现生成entrySet的代码,求解。
下面是证明的代码,不直是否有问题。
public static void main(String[] args){
Map<String, String> map = new HashMap<>();
map.put("1", "one");
Set<Map.Entry<String, String>> entries = null;
try {
Field field = map.getClass().getDeclaredField("entrySet");
field.setAccessible(true);
entries = (Set<Map.Entry<String, String>>)field.get(map);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(entries); // null
System.out.println(map.entrySet()); // [1=one]
}

这是源码,跟到这,发现找不到生成entrySet的代码
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
...全文
435 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
ltx0720 2019-07-11
  • 打赏
  • 举报
回复
EntrySet类中有
public final Iterator<Map.Entry<K,V>>iterator() {
return new EntryIterator();
}

EntryIterator extends HashIterator
HashIterator是hashmap中的一个内部类
其实就是遍历的HashMapSpliterator
XuanrenLu 2017-04-22
  • 打赏
  • 举报
回复 1
引用 3 楼 pany1209 的回复:
[quote=引用 2 楼 lxr0724 的回复:] [quote=引用 1 楼 pany1209 的回复:] EntrySet是HashMap的内部类,继承AbstractSet,你进去HashMap看看
诡异的地方在于,EntrySet, AbstractSet都是空参构造方法,但是对象new出来之后,entrySet就有值了, 但是单步调试进去却没有发现赋值的地方。[/quote] entrySet返回此映射所包含的映射关系的 Set 视图,Set并没有真是的数据,数据要从HashMap的 transient Node<K,V>[] table取,HashMap的另一个抽象内部类HashIterator才是真正赋值的地方。。可以去看看[/quote] 看明白了,调试的时候,我看到的是entrySet的size的值是1,这个值来源于HashMap 的 size,entrySet只是一个调用接口,本身没有存储entries的值,当调用iterator()的时候,返回一个可以访问HashMap 的table 的迭代器。 System.out.println(map.entrySet()); print的时候,调用了entrySet的toString方法,方法里面使用迭代器进行遍历。之前没有注意到这个细节,误以为entrySet里面有HashMap的table的引用,但是在源码里面又找不到相关的赋值操作,所以觉得很奇怪。 多谢提醒。
李德胜1995 2017-04-20
  • 打赏
  • 举报
回复
引用 2 楼 lxr0724 的回复:
[quote=引用 1 楼 pany1209 的回复:] EntrySet是HashMap的内部类,继承AbstractSet,你进去HashMap看看
诡异的地方在于,EntrySet, AbstractSet都是空参构造方法,但是对象new出来之后,entrySet就有值了, 但是单步调试进去却没有发现赋值的地方。[/quote] entrySet返回此映射所包含的映射关系的 Set 视图,Set并没有真是的数据,数据要从HashMap的 transient Node<K,V>[] table取,HashMap的另一个抽象内部类HashIterator才是真正赋值的地方。。可以去看看
XuanrenLu 2017-04-20
  • 打赏
  • 举报
回复
引用 1 楼 pany1209 的回复:
EntrySet是HashMap的内部类,继承AbstractSet,你进去HashMap看看
诡异的地方在于,EntrySet, AbstractSet都是空参构造方法,但是对象new出来之后,entrySet就有值了, 但是单步调试进去却没有发现赋值的地方。
李德胜1995 2017-04-20
  • 打赏
  • 举报
回复
EntrySet是HashMap的内部类,继承AbstractSet,你进去HashMap看看

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧