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

时间:2023-01-01 13:50:49

转载请注明原创出处,谢谢!

说在前面

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

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

上篇题目回顾

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

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

集合的重要性

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

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

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

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

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

  • 这种框架是高性能的,对于基本集合(动态数组、链表、树和散列表)的实现是高效的,并且是经过高度测试(不管是性能,安全等都是很可靠的)。
  • 集合允许不同类型的集合以相同的方式继续操作。
  • 集合是容易扩展和修改的。

集合的遍历思考

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

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

迭代器模式

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

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

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

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

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

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

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

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

在稍微多做点铺垫

  • 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 its add(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方式。

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

public static void main(String[] args) {
List<String> list = new ArrayList<String>(); 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)){ 之后,运行结果报异常,结果如图:

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

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

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

原因

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

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

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

实际工作中迭代器用法

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

思考

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

这是阿里JAVA开发手册其中一条明细,期待你的留言和分析!!!

如果读完觉得有收获的话,欢迎点赞加关注。


查阅更多历史,欢迎关注个人公众号!!!

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

阿里JAVA开发手册零度的思考理解(二)的更多相关文章

  1. 阿里JAVA开发手册零度的思考理解&lpar;一&rpar;

    转载请注明原创出处,谢谢! 缘由 阿里JAVA开发手册已经发表有很长时间了,值得认真研究思考推广 阿里官方的Java代码规范标准,这份开发手册不仅规范了一些开发细节,也提出了很多工程开发的哲学,值得好 ...

  2. 阅读阿里Java开发手册记录

    概述 在阅读完阿里Java开发手册(嵩山版)后,发现自己在开发过程中有一些没有按照规范开发的情况,这里将容易忘记的规范记录下来,并且添加自己的理解,一方面方便自己巩固记忆,另一方面希望对其他同学能够提 ...

  3. 品阿里 Java 开发手册有感

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图, ...

  4. JUC学习笔记--从阿里Java开发手册学习线程池的正确创建方法

    前言 最近看阿里的 Java开发手册,上面有线程池的一个建议: [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式, 这样的处理方式让写的同学 ...

  5. 阿里java开发手册中命名规约解读之DO&sol;BO&sol;DTO&sol;VO&sol;AO

    前言 在阅读<阿里巴巴Java开发手册>时,看到命名规则中有这样一条 虽然知道这些是根据Java对象的角色所分配名称的后缀,但是没有弄清楚分别是什么意思,日常开发中也没有使用到. 网上查找 ...

  6. 读《阿里Java开发手册》总结(1)

    一·命名约定 类名使用大驼峰式命名(领域模式相关命名除外:如DAO\VO\DO等). 常量必须全部大写,单词中间用“_”隔开(如MAX_COUNT). 抽象类命名使用Abstract或Base开头.异 ...

  7. 从阿里Java开发手册学习线程池的正确创建方法

    前言 最近看阿里的 Java开发手册,上面有线程池的一个建议: [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更 ...

  8. 【转】线程池体系介绍及从阿里Java开发手册学习线程池的正确创建方法

    jdk1.7中java.util.concurrent.Executor线程池体系介绍 java.util.concurrent.Executor : 负责线程的使用与调度的根接口  |–Execut ...

  9. 阿里Java开发手册1&period;3&period;0 文字版

    版本: 1.3.0 update: 2017.9.25 一.编程规约 (一) 命名风格 1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例:_name _na ...

随机推荐

  1. String Aop 动态代理例子

    动态代理原理:spring AOP采用动态代理来实现 (1)定义一个接口Boy package aop001; public interface Boy { public void beat(Stri ...

  2. C&plus;&plus;11笔记&lt&semi;一&gt&semi;

    目录: 1.std::share_ptr智能指针: 2.std::tr1::function模板类: 3.stringstream: 4.set/vector/map: 5.static_cast&l ...

  3. Python3 windows如何安装模块 setuptools

    下载的module解压后里面有setup.py文件,如果打开setup.py文件里面有这段代码: from setuptools import setup ... setup( ... 这种的都需要调 ...

  4. icmp&comma;tcp&comma;traceroute&comma;ping&comma;iptables

    有东莞的监控主机到北京BGP出问题了: 报警短信疯狂发送: 找东莞IDC和北京BGP服务商协查: 有个奇怪的问题:北京到东莞trcaceroute都有路由信息 东莞143段到北京全无路由信息:但,东莞 ...

  5. hrbustoj 1179&colon;下山(DFS&plus;剪枝)

    下山Time Limit: 1000 MS Memory Limit: 65536 KTotal Submit: 271(111 users) Total Accepted: 129(101 user ...

  6. 【经验】Windows7、8、8&period;1 MSI安装错误Error Code 2502 &amp&semi; 2503 解决方法

    [因] 今天升级TortoiseSVN到1.8.8,出现问题:Error Code 2502 & 2503,一直不能安装成功. 上网一搜,国内没找到好的解决方法,在一个外文网上找到了方案,原链 ...

  7. cf C&period; Jeff and Rounding

    http://codeforces.com/contest/352/problem/C 题意:给予N*2个数字,改变其中的N个向上进位,N个向下进位,使最后得到得数与原来数的差的绝对值最小 对每一个浮 ...

  8. grok 官方文档

    <pre name="code" class="html">grok: 解析任意文本并构造它: Grok 是当前最好的方式在logstash 解析蹩 ...

  9. Image控件

    前台代码: <asp:Image ID="Image1" runat="server" /> 后台代码; protected void Page_L ...

  10. 如何恢复已禁用的console&period;log?

    如何恢复已禁用的console.log? How to Restore a Disabled console.log?通过将其拉出iframe,在已删除的页面(如twitter)上恢复console. ...