阿里JAVA开发手册零度的思考理解(二)

说在前面

人生的大道上默默地走,就必须要有一盏灯亮着为你引导方向!而这盏灯抑或只是一句话,一句鼓励,一个赞美,一次承认,一次认可,一次相识一次交流……

上篇文章:阿里JAVA开发手册零度的思考理解(一)得到作者孤尽的肯定支持,那是一个小激动啊,我会继续努力,继续阅读和思考阿里JAVA开发手册,毕竟每一条都是前人踩过的坑,通过血的教训总结出来的。

上篇题目回顾

阿里JAVA开发手册

看完这条,个人觉得主要是集合相关操作,在JAVA基础中集合这块的重要性也的确非常重要(毕竟是用到最多的),本期只会结合上题进行一些简单扩展,并不会涵盖所有集合操作,也不涉及集合是否线程安全这块,后期我会在我的系列高并发、锁系列里扩展深入。

集合的重要性

已经有数组了为什么会出现集合呢?依然清晰的记得数据结构里面顺序结构、链式结构的特点。在这里数组就属于顺序结构(但是集合里面根据顺序结构或者链式结构实现的都有,所以在选择用那个的时候最起码需要有那么一点点思考而不是拿什么用什么)。

数组一旦定义,长度将不能再变化。并且数组仅仅是一个一连串的变量而已,对于很多重复的操作(并没有进行统一的抽象)而且有些顺序结构并不太适合,需要链式结构实现适合或者是需要顺序结构与链式结构结合实现才比较合适。

备注:对于很多重复的操作,比如如果需要扩容,需要自己实现,根据编码水平不同实现的效率不一样(而且这个可能大量存在,每个人都需要实现,不符合工程学的思想),再比如需要排序,增删,遍历等等。

上面的一些问题就引入了集合并且解决了这些问题,所以集合非常重要,并且项目中集合到处可见,需要把db,nosql里面的数据接收下来。

下面看看集合具备的几个特性 :

这种框架是高性能的,对于基本集合(动态数组、链表、树和散列表)的实现是高效的,并且是经过高度测试(不管是性能,安全等都是很可靠的)。

集合允许不同类型的集合以相同的方式继续操作。

集合是容易扩展和修改的。

集合的遍历思考

集合遍历,从工程学我们需要提供一种方法顺序访问一个集合对象中的各各元素,而又不需要暴露该对象的内部表示

如何才能做到呢??? 迭代器模式就可以做到,下面带大家一起去了解下。

迭代器模式

迭代器模式的功能主要在于提供对聚合对象的迭代访问。主要就是这个访问进行做文章的。那么为什么使用迭代器模式呢?有什么好处呢?

集合对象的类型很多,如果对集合对象的迭代访问跟集合对象本身融合在一起的话,会严重影响到集合对象的可扩展性和可维护性。

备注:迭代器模式的关键思想就是把对集合对象的遍历和访问从集合对象中分离出来,放到单独的迭代器中,这样集合对象会变得简单一些;而迭代器和集合对象可以独立的变化和发展,这样就大大增强类系统的灵活性。

一般情况下面,使用的都是外部迭代器(由客户端来控制迭代器的下一个元素的步骤,就是在代码里面我们需要手动调用next来迭代下一个元素,这样做就是要灵活点)

JDK5之后引入的新特性foreach( 增强版for)

备注:通过使用javap查看反编译代码,在数组里面,是固有的foreach实现,直接循环数组,而在容器的迭代foreach是通过迭代器来实现。

数组foreach

容器的迭代foreach

在稍微多做点铺垫

ArrayList对Iterator接口实现

备注:ArrayList里面对Iterator实现了2种,一种是普通的从前向后,而第二种是双向迭代输出,可以从往前也可以往后。

解题

阿里JAVA开发手册

上面说了那么多,我觉得现在可以开始解题了,各位看官久等了。并发系列又是另外一个重要的话题,先不考虑并发进行分析,如果并发操作,需要对Iterator对象加锁,这个应该好理解。

This field is used by the iterator and list iterator implementation returned by the iterator and listIterator methods. If the value of this field changes unexpectedly, the iterator (or list iterator)will throw a ConcurrentModificationException in response to the next, remove, previous, set or add operations.This provides fail-fast behavior, rather than non-deterministic behavior in the face of concurrent modification during iteration.

Use of this field by subclasses is optional. If a subclass wishes to provide fail-fast iterators (and list iterators), then it merely has to increment this field in itsadd(int, E) and remove(int)methods (and any other methods that it overrides that result in structural modifications to the list). A single call to add(int, E) or remove(int) must add no more than one to this field, or the iterators (and list iterators) will throw bogus ConcurrentModificationExceptions. If an implementation does not wish to provide fail-fast iterators, this field may be ignored.

所以应该注意,并不仅仅包括remove,add元素也请使用Iterator方式。

这一条标准是加了强制的,说明了重要性,按照上面的优秀实践去做就对了。

publicstaticvoidmain(String[] args){        List list =newArrayList();                list.add("1");        list.add("2");for(String item:list){if("1".equals(item)){//(1    换成  if("2".equals(item)){list.remove(item);            }        }    }

当(1  换成  if("2".equals(item)){  之后,运行结果报异常,结果如图:

结果

其实这种给出了错误,并且有代码行数的情况其实发现查找问题都挺方便的,其实该问题的重点就变成了都是基于Iterator的输出,但是在进行删除元素的时候应该用那种方式才正确。

没有必要纠结为什么1不错,而2错,稍微看下源码就知道了,其实我们也可以让2不错,只是jdk里面就是这样实现的,它的解释和考虑如下原因。

原因

ArrayList此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

快速失败

所以最佳实践就按照阿里java开发手册里面那样就好了,add元素也请使用Iterator方式。

实际工作中迭代器用法

可能说完,大家感觉迭代器就仅仅在集合遍历里面用,而且都已经有了,其实实际中的确有一些用法,反正都是围绕控制访问的,比如分页,非常常见的情况,如果每次都基于数据库分页那么怕性能不好,如果完全在内存(内存太贵,数据太多,不现实),一般的做法就是比如一页20条数据,我们一般可以每次查询数据库的时候取5页到内存(具体每次取多少可以根据用户行为分析,得到一个比较合理的,而且越到后面访问的机会越少,取到内存的就越少了,可以先比如每次都是取n页数据,在多少页之后每次取m页 之后在每次取一页一页了。n>m>1)。那么比如取出来的100条数据在内存中,需要进行根据分页访问,而原来的jdk里面的好像不满足,那么自己实现一个类似的是不是特别灵活呢?后续有空,我会在我的微信公众号,系列文章的技术思考里面把类似这块分析下的。

思考

阿里JAVA开发手册

作者:匠心零度

链接://www.greatytc.com/p/f2355c17ca28

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容