可以看到第7行代码处是调用了ArrayList的remove操作进行删除的,但同时注意第10行代码处会将expectedModCount更新为此时modCount的最新值,这样在next方法中就不会抛出异常了;在第8行代码处会将cursor更新为lastRet(lastRet代表上一次的索引位置),即将cursor-1(因为此时要remove,所以cursor指针需要减一)。这样在hasNext方法中就会返回正确的值了。
6.3.2 add操作 虽然iterator方法可以提供remove操作来使删除能正确执行,但其却没有提供相关add方法的API。无妨, ArrayList中为我们提供了listIterator方法,其中就有add操作(如果一定要用迭代器方式来实现的话)。相关的示例代码如下:
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); ListIterator<String> iterator = list.listIterator(); while (iterator.hasNext()) { String item = iterator.next(); if ("1".equals(item)) { iterator.add(item); } } 同上,首先来看一下第5行代码处的listIterator方法: public ListIterator<E> listIterator() { return new ListItr(0); } listIterator方法返回了一个ListItr内部类。那么就来看一下ListItr的代码实现:
private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } //... public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } } 可以看到ListItr内部类是继承了Itr类,包括hasNext和next等方法都是直接复用的。而在add方法中的第14行代码处,是调用了ArrayList的add操作进行添加的。另外和Itr的remove方法一样,第17行代码处也是在更新expectedModCount为此时modCount的最新值,第15行代码处的cursor更新为+1后的结果(因为此时是在做add操作)。这样后续的hasNext和next操作就不会有问题了。
题外话在应用业务里待太久很多底层的东西往往容易忽略掉,今年的年初计划是把常用的JDK源码工具做一次总结,眼看年底将近,乘着最近有空,赶紧的给补上。在这行干的越久真是越觉得:万丈高楼平地起,这绝B是句真理!
ArrayList你真懂?说说foreach与iterator时remove的区别
你是否想过互联网公司一面为什么总爱问集合?聊聊经典数据结构HashMap
AQS源码深入分析之独占模式-ReentrantLock锁特性详解
AQS源码深入分析之共享模式-为什么AQS中要有PROPAGATE这个状态?
AQS源码深入分析之条件队列-Java中的阻塞队列是如何实现的?
AQS源码深入分析之应用工具CountDownLatch(规划中)
AQS源码深入分析之应用工具CyclicBarrier(规划中)
ConcurrentHashMap源码分析-ConcurrentHashMap在Java 8中的实现还有bug?而且还不止一处!这个坑还比较大,后面会重点总结一下!
ThreadPoolExecutor源码分析-问烂了的Java线程池执行流程,其实如果问的细,很多人还是一脸懵逼?
ScheduledThreadPoolExecutor源码分析-重点屡屡定时线程池是如何实现延迟执行和周期执行!
ThreadLocal源码分析-重点总结,内存泄漏,软引用弱引用虚引用,面试经常喜欢问,我也喜欢问别个
红黑树TreeMap、LinkedHashMap(不确定要不要写,有时间写,看项目情况)
有序并且线程的Map容器ConcurrentSkipListMap(跳表)深入理解
LinkedList(不确定要不要写,有时间写,看项目情况)
年底如果项目不赶,有空就在写一篇常用的排序算法的文章
每一次总结都是对知识点掌握程度的审视,技术不易,每日精进一点,与大家共勉。