当前位置: 首页 > news >正文

网站举报在哪举报石家庄seo扣费

网站举报在哪举报,石家庄seo扣费,宣传海报在什么网站做,注销网站和取消接入本文能解决的疑惑: idea在debug时偷偷调用toString方法,在HashMap追源码时产生的疑惑HashMap的entrySet()和keySet()方法真的创建了一个存满数据的set对象吗?内部类:EntrySet类没有构造器,那它是怎么初始化的呢&#…

本文能解决的疑惑:

  1. idea在debug时偷偷调用toString方法,在HashMap追源码时产生的疑惑
  2. HashMap的entrySet()和keySet()方法真的创建了一个存满数据的set对象吗
  3. 内部类:EntrySet类没有构造器,那它是怎么初始化的呢?
  4. 为什么集合框架中一定要利用好迭代器iterator()来获取入口
  5. entrySet().size()获取的值是该set的实际大小吗?

entrySet()和keySet()详解

  • entrySet()和keySet()方法都是返回一个set对象,并且在debug时也能看到set的值和size;但是源码中并没有利用构造器对其初始化。
  • 在此文中以entrySet()举例,来阐述entrySet和keySet的生命周期

测试代码示例,并提出问题

    HashMap hs = new HashMap();hs.put("啊啊", "2");hs.put("2", "2");hs.put("3", "2");hs.put("4", "2");hs.put("5", "2");hs.put("6", "2");hs.put("7", "2");hs.put("8", "2");hs.put("9", "2");Set entrySet = hs.entrySet();//1.获取entrySet对象System.out.println(entrySet );//2.结果:正确输出了上面put的内容Object[] objects = entrySet .toArray();System.out.println(objects[3]);//3.结果:正确打印了5=2Iterator iterator = entrySet .iterator();//4.获取迭代器while (iterator.hasNext()){//5.迭代器遍历Map.Entry next = (Map.Entry) iterator.next();next.getKey();next.getValue();}
  • 如果在idea中使用debug对Set entrySet = hs.entrySet()打断点,你会发现即便是没有运行到第二步,debug信息栏中已然出现了该set全部的内容。
  • 跟着debug一直step into进行分析,发现并没有任何一个方法对entrySet对象进行过赋值,那么hashMap对象中的内容是如何进入到entrySet中的呢?

1 debug分析

new EntrySet()

  1. 没有找到构造函数

  1. AbstractSet中只有一个空参且空函数体的方法

第一个结论:entrySet是空对象

entrySet只是new出来了,但它是一个没有内容的空对象。

2第二个问题:entrySet对象调用方法时为何有值?

既然 Set entrySet = hs.entrySet()出来的entrySet 对象是个空对象,那为何System.out.println(entrySet );
Object[] objects = entrySet .toArray();
Iterator iterator = entrySet .iterator()
对entrySet对象进行调用方法的时候却能正确的执行呢?

2 源码分析

toString方法

System.out.println(entrySet ); 显然调用的是toString方法;

  • 在2.5中的源码可知entrySet对象继承于AbstractSet类,间接实现了AbstractCollection接口
  • 重写的toString()方法调用了this.iterator()即EntrySet类的iterator()方法进行输出

iterator方法

  1. 我们发现HashMap中的内部类EntrySet中重写了iterator()方法,实际调用的是EntryIterator对象

  2. EntryIterator类继承于HashIterator类 :nextNode方法是HashIterator中的方法
    EntryIterator

  3. 跟进nextNode方法,框体内容是指针的变化的判断细节,不是本论题的重点


由此可知:

这个EntrySet类重写的iterator()方法可以使得指针正确得指向下一个节点

toArray方法

  • 测试代码中也正确输出了toArray()的结果,同样的,这个方法也是重写在其父类AbstractCollection中的
  • 同理,其底层实现还是调用了iterator(),利用HashIterator类中的nextNode()方法对指针进行下移

size、clear方法

这两个方法很简单,就是直接用的当前HashMap对象的属性和方法

hashMap.entrySet().size()的大小并不是真正这个entrySet对象的大小,而是调用了size属性的fake size

3小总结

  • entrySet()和keySet()都是懒汉式,调用方法,new对象的时候并没有对其进行赋值,并且其size()方法也是一个虚假的size
  • 而是在使用hashMap.entrySet().toString()、hashMap.entrySet(). toArray() 等方法的时候才调用iterator()来获取迭代器
  • EntrySet类和KeySet类也都没有构造器能进行初始化
  • 不得不说HashMap的设计十分精巧,entrySet()表面上获取了一个set对象,实际上这个set对象是空的,几乎所有的方法都是先直接获取迭代器入口节约内存的同时性能大幅提升

补充:putVal()方法和entrySet()无关

在翻阅资料的时候看到很多人说是putVal()方法中调用了resize()来维护了entrySet(),在看完源码之后才会发现这种说法是没有根据的。

resize()放是扩容的方法,代码中也没有出现任何的跟EntrySet相关的逻辑

补充:new HashSet();

根据以上的思路就可以知道,集合中Set底层为什么调用的是Map,你看源码中new HashSet()也是new了一个HashMap,两者逻辑可以完全复用

4关于idea在debug时的问题

参考

  • DEA在debug时,当debug到某个对象时,会调用对象的toString()方法,用来在debug界面显示对象信息。
  • IDEA调用toString()方法时,即使在toString()方法中设置了断点,该断点也不会被触发,也就是说,开发者多数情况下不会知道toString()方法被调用了。
  • 多数情况下调用一下toString()方法没有什么问题,但是也有例外,比如重写了toString()方法的类,随意的调用toString()方法会导致未知的问题本案例就是因为重写toString()方法而产生了问题
http://www.lbrq.cn/news/2501371.html

相关文章:

  • 如何攻击网站深圳网络推广专员
  • 网站通内容管理系统指定关键词seo报价
  • 网站建设学生兼职刷赞抖音推广网站
  • 环保公司网站建设宣传图片网站查询器
  • 没学过计算机开始学做网站百度医生在线问诊
  • 郑州网站建设 推广seo外包公司费用
  • php网站用的是什么语言写的玄幻小说百度风云榜
  • 新疆网站建设咨询北京seo工程师
  • 优秀网站的特点百度竞价推广流程
  • 做婚恋交友网站模板快速排名优化推广手机
  • 网站建设 点指成名广州中小企业seo推广运营
  • 完整域名展示网站源码百度浏览器下载安装2023版本
  • ios wordpress连接站点简述什么是网络营销
  • 电子商务seo招聘seo快速排名软件网址
  • wordpress修改描述国外搜索引擎优化
  • 个人可以做公益网站吗爱站长
  • 网站建设合同 免责声明重庆网站外包
  • 网站制作有哪些种类seo标题优化关键词
  • 用bs做网站谷歌官网下载
  • 学网站ui设计网络热词2021流行语
  • 网站建设需要哪些工具与知识seo独立站
  • 网站做管理后台需要知道什么长沙百度搜索网站排名
  • 用别人的二级域名做网站app推广代理加盟
  • 有谁会设制网站免费引流微信推广
  • 网站开发 确认函南京百度推广
  • wordpress h5 app锦绣大地seo
  • 青海省公路建设网站百度爱采购优化排名软件
  • 郑州网站建设乛汉狮网络哈尔滨网络优化推广公司
  • 防城港网站开发排位及资讯
  • 开一个网站建设公司好seo网络优化公司哪家好
  • TCPIP之常用协议
  • Nginx 四层(stream)反向代理 + DNS 负载均衡
  • C++ 内存管理
  • 基于Java的KTV点歌系统的设计与实现
  • Keil MDK 嵌入式开发问题:warning: #223-D: function “sprintf“ declared implicitly
  • 哈尔滨←→南昌的铁路要道