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

哈尔滨快速建站案例二级网站域名

哈尔滨快速建站案例,二级网站域名,嘉兴网站建设需要多少钱,网页翻译不见了目录 一.前言 二.正文 1.我写的类为什么不能使用增强for(迭代器遍历) 2.代码健全性——迭代器常见的两个Exception 1.NoSuchElementException 2.ConcurrentModificationException 三.后言 一.前言 本篇面向对象主要为和我一样的小白,主要是对迭代器模式的浅…

目录

一.前言

二.正文

1.我写的类为什么不能使用增强for(迭代器遍历)

2.代码健全性——迭代器常见的两个Exception

1.NoSuchElementException

2.ConcurrentModificationException

三.后言


一.前言

本篇面向对象主要为和我一样的小白,主要是对迭代器模式的浅析和实现,会以大家最常见的ArrayList作为举例也会带着大家去分析一下源码,为了便于理解尽量口语化

本篇采用Kotlin代码,但以Java源码进行解析,因为首先最近实习一直在用Kotlin,其次这两个语言真的太像了,甚至源码都能说很多一样,想让大家可以注意到这门语言。

Kotlin 是一种在 Java 虚拟机(JVM)上运行的静态类型编程语言,由 JetBrains 开发,Kotlin 代码更为简洁,减少了样板代码,能让开发者以更少的代码实现相同功能。

二.正文

1.我写的类为什么不能使用增强for(迭代器遍历)

增强for循环相信大家都写过,如下图:

这样我们可以访问list中的每一个元素,接下来我们定义一个Student类来试试

Student类中有name和age两个属性 

下图可以看到我们对student对象使用增强for失败了,那这是为什么呢,那么,我们就要去ArrayList里面找找原因了,去找找这个for ArrayList实现的上级接口是Collection:

可以看到Collection继承了Iterable接口,我们接近跟进,我们找到了增强for,这段英文的大概意思是实现了这个接口那么对象就可以使用增强for

那好办了,那我就让Student类实现这个接口试试呗,泛型就随便填个String,继承这个接口需要重写iterator方法,这个方法返回Iterator对象,返回的这个其实就是迭代器对象

我们跟进 Iterator接口,可以看到里面有next方法和hasNext方法

而我们又知道增强for循环的另一种写法也就是迭代器遍历(增强for的底层就是调用迭代器遍历),看两个函数的返回类型我们就可以猜到,hasNext函数返回布尔类型用于循环判断条件,next用于拿取元素,那我们先写一个迭代器遍历的代码,然后来简单看看ArrayList是怎么实现这几个方法的

进入iterator方法,可以看到iterator方法返回了一个对象

这个对象是ArrayList的一个内部类,也就是说ArrayList通过调用iterator方法获取迭代器其实是得到了Itr对象,这个内部类实现了Iterator接口,所以重写了next方法和hasNext方法,不必了解太多,后面再分析源码,你只要知道这里的hastNext在判断是否越界,next方法用于返回当前访问到的元素,cursor就是一个变量来表示访问到了第几个元素

那思路就清晰啦,我来给你梳理一下:增强for循环就是迭代器遍历,想要对象可以进行迭代器遍历,就要相应的类实现Iterable接口,表示可迭代的,实现了这个接口就要重写iterator方法,这个方法是用于暴露到外界来获取迭代器对象的,所以我们肯定要有一个类来表示迭代器对象,在这里定义成内部类再合适不过啦,定义的内部类迭代器对象需要实现Iterator接口,重写两个函数来表示迭代器的具体实现逻辑。

这种实现方式将很多信息隐藏在底层,这里就要扯出迭代器模式的概念了,如下:

迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。

 那我们就可以自己给Student实现迭代器功能,比如说来访问Student类的对象的每一个属性的值如下图,我们让Student的iterator方法返回我们定义的一个实现了Iterator接口的内部类StudentIterator,为了不报错,需要重写hasNext和next两个方法

这里的思路很简单啦(代码健全性先暂不考虑,我们先简单实现逻辑,之后慢慢来盘哈),我们定义三个变量,elementArray用来表示外部类的每个属性,这里为数组类型,泛型为Field,这里的Field全类名为java.lang.reflect.Field,看到reflect你可能猜到,这里的elementArray是通过反射拿到的,这里采用反射来拿信息,就不用内外类交互了。arrayLength是属性数组的长度,count是指针,用来表示遍历到第几个元素了,然后再init代码块中初始化变量

 这里注意一下,elementArray表示的是Student类的每个属性名,而不是值,为了接下来的讲解不会让某些点让大家感到疑惑,我这边展示一下反射拿到属性每个值的代码:

接下来我们实现next方法,上图中我们可以看到反射拿取值element.get(student),element我们已经有了,就在数组里,对象怎么拿到?别忘了Student类是返回了一个StudentIterator对象回去,那我们我可以利用构造函数传递呀,则hasNext实现如下两图: 

2.代码健全性——迭代器常见的两个Exception

1.NoSuchElementException

换句话就是数组越界了,有人疑惑了,不是?我hasNext判断了啊,而且next里指针每次就加一,这些代码符合迭代器模式,都在底层没暴露出去,外界修改不了指针的值呀,怎么会越界,你这种想法是建立在调用一次hasNext后只调用一次next,如下图代码:集合内只有5个元素,但调用了多次next

我们可以看到ArrayList源码中就在next中做了判断:

所以我们也做个判断,让我们的StudentIterator代码更加健全: 

2.ConcurrentModificationException

从英文字面上理解就是在遍历过程中对集合进行了修改,当然这里所说的修改是指手动删除添加元素(Iterator其实在内部提供了一个remove方法让我们安全得删除元素),也就是改变集合的长度,写过迭代器的朋友肯定知道这个报错,让我们来看看ArrayList源码中在哪抛的这个错误

跟进如下图,我们这里是浅析就不分析每个变量,下面的代码就是在判断集合长度是否变化了,在这里你肯定很疑惑,为什么要做这个判断?

这个问题我之前也想了一会,我来给一种说法,看如下代码,假如遍历到的元素为5,就添加一个5到集合元素中去,我们知道,集合的底层实现其实就是个数组,假如我们添加元素是将元素添加到最后面,那么这个迭代遍历永远不会结束,假如我们是把元素添加到前面,那每次添加元素意味着数组要移位一次,假如数组很大,时间复杂度是不小的,所以我想这个错误是为了避免这些极端情况

三.后言

好啦,看到这我相信你已经能得心应手得实现一个迭代器啦,也懂了一部分集合源码,ArrayList的源码就不说啦,因为上面所有内容就算讲了一遍了,第二个错误的健全代码也不说啦,我希望你自己去看源码自己实现,也挺简单的,第一次开坑设计模式系列,看大家喜不喜欢这类小白文再考虑要不要实习期间花时间更新吧,有问题欢迎在评论区交流,我也是初学者,共勉

http://www.dtcms.com/wzjs/533068.html

相关文章:

  • 商务网站建设PDF下载wordpress一键关注
  • 做网站创业流程图重庆网上房地产官网查询
  • DW怎么做电商网站仿网链网站源代码下载
  • 北京城建建设工程有限公司网站怎么做时光网站
  • 用html5设计个人网站修改wordpress登录地址
  • 提供做网站重庆在线最新招聘信息
  • 微信小程序开发零基础入门网站关键词如何优化上首页
  • 网站做数学题wordpress二次开发难吗
  • 陕西网站建设策划内容中国早期互联网公司
  • 北京网站seo收费标准vps远程桌面服务器
  • 比较好的网站公司WordPress添加运行时间
  • 百度网站建设流程北京网站开发哪家专业
  • 北京大兴网站建设首选公司宣传片视频创意
  • 如何自己制作一个网站wordpress 归档
  • 大连设计网站的公司网站如何建设二级域名代理
  • 展示型网站建设流程wordpress建站产品导入不同目录
  • wordpress文章摘要调用长沙seo网络营销推广
  • 网站建设与规划实验报告福建省建住房建设部网站
  • 代做动画毕业设计的网站工作室建设
  • 手机微信小程序开发教程seo综合查询站长工具怎么用
  • 做政协网站的目的是什么做网站的画布是多少
  • 网站开发学校如何做拼多多商城官网站
  • 厦门市建设局查询保障摇号网站首页服务平台图片
  • 网站开发的收获体会房子做水电的时候是不是要先埋网站
  • 重庆低价网站建设修改wordpress时区
  • 网站开发vs2013城阳天河小学网站建设
  • 重庆网站快速排名提升网站与网页的关系
  • 企业门户网站系统H5网站整站
  • 网站地图格式网站结构是什么 怎么做
  • 找设计方案的网站域名查询是否被注册