提示

文中涉及知识点:

  • Collection 、 Iterator
  • Guava 中的 Lists.partition 方法

如果你对这两个知识点不了解,强烈建议阅读文中引用的参考文章。

场景一:以ArrayList为例

参考文章 java迭代器失效Collection与Iterator的remove()方法区别与ConcurrentModificationException异常 ,可将迭代器和 Collection 的不同理解为:迭代器是基于 Collection 的一个视图,迭代器执行诸如 remove 和 add 之类的操作时,会首先在底层 Collection 上操作,最后将 expectedModCount 更新为新的 modCount ,而直接操作 Collection 则只会更新 modCount ,导致 fail-fast 机制生效。因此我们应在涉及到此类操作时尽可能只使用迭代器,可参考文章 Java:使用Iterator迭代器遍历集合数据

场景二:以Guava中的Lists.partition为例

参考文章 列表分片实现Java 集合细节(三):subList 的缺陷 ,可知 Lists.partition 的底层实现就是 subList 方法,而 subList 函数返回仅仅只是一个视图,因此这里的 subList 其实和前面所述的迭代器在概念上是一样的(只是新的分片 List 的计数变量不叫 expectedModCount,而是和原 List 一样的 modCount,通过 this 区分),它们都是在原 List 的上层产生的视图,然后我们使用这个视图进行各种操作。因此,第二篇文章中所谓的 subList 缺陷其实不能叫做缺陷:我们在原 List 上通过 subList 获得其分片视图后,就不应该再操作原 List 了(类似于迭代器,我们获得一个 List 的迭代器后,应使用该迭代器进行各种操作,如前所述,此时针对原 List 的一些操作是危险的)。

当然,第二篇文章之所以将其称为“缺陷”也有原因:我们通常会认为获得的新分片 List 是新的 List ,这就是语言层面的理解了。

场景三:浅谈Guava中的集合类

其实,Guava中的多种集合如Maps、Lists均没有实现自定义的add操作。以Lists为例,当我们用Lists.transform或是Lists.partition函数返回新的集合时,都是Lists的内部类,这些内部类同样没有实现add方法,因此当我们视图在新的集合上进行add操作时,就会调用AbstractList的add方法,此方法会直接抛出UnsupportedOperationException。不过,我们仍旧可以在旧的集合中进行add操作,此时新集合也能看到刚刚add进去的元素,这是需要注意的。

总结

有时很多概念描述有很大不同,其实内部原理是相通甚至相同的,将这些概念融会贯通将大有裨益。
如果你了解 C++ 的话,可以参考 vector 容器的 insert 和 erase 方法,其实底层原理和 java 也是类似的。

扩展:多线程场景

注意,ArrayList并不是线程安全的,若不追求数据强一致性,可使用 CopyOnWriteArrayList 方法,可参考 聊聊并发-Java中的Copy-On-Write容器JDK 5.0 中更灵活、更具可伸缩性的锁定机制

其他扩展文章

为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作

谈谈知识的融会贯通:以“java中的迭代器失效问题”为例的更多相关文章

  1. Java基础知识强化106:Java中 int 的各进制之间的转换

    1.二.八.十.十六进制之间的转换  下面是示例代码,我们直接通过JDK工具库中的方法实现的,如下: public static Integer valueOf(String s, int radix ...

  2. Java基础知识强化101:Java 中的 String对象真的不可变吗 ?

    1. 什么是不可变对象?       众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对 ...

  3. Java基础知识强化03:Java中的堆与栈

    1.在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JV ...

  4. Java基础知识强化10:Java中的中间缓存变量机制

    1.对于自增运算++j与j++,由于加一的执行顺序不同,所以Java中有中间缓存变量来储存其单个表达式的值,而j的自增自减的结果依然保留在原来的变量储存区.因为本体是j的值,而单个表达式的值是中间产生 ...

  5. Java基础知识强化19:Java中switch分支语句

    java中switch语句: 这里expression控制表达式的数据类型只能是byte.short.char.int四种整型类型和枚举类型,不能是boolean类型: Java7(1.7)改进了sw ...

  6. Java基础知识强化24:Java中异常

    1.什么是异常 ?       Java程序运行中,常常会遇到非正常的现象,这种情况称为运行错误.根据性质可以分为错误和异常.Java程序中(无论谁写的代码),所有抛出(throw)的异常都必须从Th ...

  7. Java基础知识强化22:Java中数据类型转换

    数据类型转换: (1). 自动转换 低级变量可以直接转换为高级变量,这叫自动类型转换.比如: byte b: int b:  long b:  float b:   double  b: 上面的语句可 ...

  8. Java基础知识强化21:Java中length、length()、size()区别

    1.java中的length属性是针对数组说的,比如说你声明了一个数组,想知道这个数组的长度则用到了length这个属性.2.java中的length()方法是针对字符串String说的,如果想看这个 ...

  9. 第一篇 网站基础知识 第4章 Java中Socket的用法

    第4章 Java中Socket的用法 4.1 普通Socket的用法 Java中的网络通信是通过Socket实现的,Socket分为ServetSocket和Socket两大类,ServetSocke ...

随机推荐

  1. Ural 1966 Cycling Roads

    ================ Cycling Roads ================   Description When Vova was in Shenzhen, he rented a ...

  2. Java并发编程基础——同步

    一.synchronized 关键字 1)synchronized 锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class 类对象.如同下面例子所示: package cn.test. ...

  3. Python爬虫学习之正则表达式爬取个人博客

    实例需求:运用python语言爬取http://www.eastmountyxz.com/个人博客的基本信息,包括网页标题,网页所有图片的url,网页文章的url.标题以及摘要. 实例环境:pytho ...

  4. 技术干货:实时视频直播首屏耗时400ms内的优化实践

    本文由“逆流的鱼yuiop”原创分享于“何俊林”公众号,感谢作者的无私分享. 1.引言 直播行业的竞争越来越激烈,进过2018年这波洗牌后,已经度过了蛮荒暴力期,剩下的都是在不断追求体验.最近正好在做 ...

  5. Javascript高级编程学习笔记(40)—— DOM(6)CDATASection、DocumentType

    CDATASection类型 CDATASection类型是只针对XML文档的类型 因为浏览器无法解析 在浏览器中创建CDATASection的函数也无法正常使用 该类型有以下属性 nodeType: ...

  6. 通过代码定义shape/selector

    public class DrawableUtil { /** * 定义一个shape资源 * * @param rgb * @param corneradius * @return */ publi ...

  7. PHP中的自动加载

      自动加载? 或许你已经对自动加载有所了解.简单描述一下:自动加载就是我们在new一个class的时候,不需要手动去写require来导入这个class.php文件,程序自动帮我们加载导入进来.这是 ...

  8. 如何将一个文本内容通过PHP 以表格的方式输入到页面上

    如何将一个文本内容通过PHP 以表格的方式输入到页面上 <?php //读取文本内容 $contents = file_get_contents("names.txt"); ...

  9. C# 配置文件Xml读写

    分析xxx.exe.config文件: <?xml version="1.0" encoding="utf-8"?> <configurati ...

  10. 整理+学习《骆昊-Java面试题全集(上)》

    ★可以关注微信公众号,了解更多技术和行业信息 2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅读了以后发现里面的很多题目是重复且没有价值的题目,还有不 ...