Kotlin刨根问底(二):for循环引起的一起“血案”(上)

简介: 本文灵感来源于:群友遍历列表时remove元素引发异常,后对for循环的实现原理进行一系列的探究~

0x0、要点提炼


  • 普通for循环」类似代码,Java不报错,Kotlin却数组越界,因「循环条件不一样


Java先判断是否满足条件执行循环体自增


Kotlin遍历的是范围,直接进循环体


  • 增强for循环」=  while循环 + 迭代器Iterator


  • 迭代器的设计哲学」→ 将 遍历行为被遍历对象 分离,无需关心容器底层结构;


  • ConcurrentModificationException」异常原因(通过两个字段配合)


modCount → 记录列表结构修改次数,调用列表的remove方法,此值+1

 

expectedModCount → 预计修改次数,调用Itr迭代器中的remove方法时,会调用列表的remove方法,而后将modCount赋值给expectedModCount,即保证遍历过程中两个值是相等的;

 

如果此时调用列表的remove方法modCount增加1,而迭代器中的expectedModCount没变,两者不等,就会引发ConcurrentModificationException异常。


  • fail-fast(快速失败)」


做系统设计的时候先考虑异常情况,一旦发生异常,直接停止并上报,一种用于提前预警的Bug检测机制;在集合中的应用就是:在遍历一个集合时,当集合结构被修改,直接抛出异常。


  • 规避ConcurrentModificationException的几种方法」


  • 单线程:使用迭代器进行remove;
  • 多线程:在使用迭代器处加锁(如synchronize);
  • 使用fail-safe(安全失败)机制的同步容器,如CopyOnWriteArrayList,在java.util.concurrent包中;


  • Kotlin中使用toList()后可以规避异常的原因


创建了新的ArrayList用作遍历,remove移除的是旧ArrayList的元素,故互不影响


0x1、起因


寒冷的午后,在一个交流群里,一位开发者盆友抛出了下面的问题:



同时附带两张截图




刚好在写代码的我,随手点开了 toList() 的源码:



惯性思维 回了句:涉及到可变列表和不可变列表吧


接着截了个 Collection.kt 的文件结构图后,追加:



其实我并没有理解他的问题,就开始跟起了RecyclerView的源码,再经历过一番排查得出:


应该和 Iterable,普通for循环,增强for循环有关


然后被拉去开了个两个半小时的用例评审…回来看到问题还没解决,看了聊天记录,捋了一下才弄懂他的问题:


1、普通for循环(下标遍历),类似的代码,Java不报错,Kotlin却抛 IndexOutOfBoundsException


2、增强for循环(foreach),remove移除,都会抛 ConcurrentModificationException


看不懂?写个简单的代码演示下问题:


① Java



② Kotlin


初始化列表:



行吧,接着一个个讲解~


相关文章
|
3天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
|
10天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
|
8天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
16 2
|
16天前
|
Java Kotlin 索引
Kotlin教程笔记(9) - 分支与循环
Kotlin教程笔记(9) - 分支与循环
30 5
|
19天前
|
Java Kotlin 索引
Kotlin教程笔记(9) - 分支与循环
Kotlin教程笔记(9) - 分支与循环
27 2
|
23天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
45 4
|
5月前
|
Kotlin 索引
Kotlin中循环语句
Kotlin中循环语句
|
30天前
|
Java 开发者 Kotlin
Kotlin开发笔记- 分支与循环
本系列教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,可参考“简洁”系列教程。本文重点介绍了Kotlin中的分支语句(if...else 和 when)及循环语句(for 和 while),并提供了丰富的示例代码,帮助读者掌握这些核心语法。
26 1
|
10天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
20 0
|
1月前
|
Java Kotlin 索引
Kotlin12 - 分支与循环
Kotlin 12- 分支与循环
20 2