为什要写这个,因为,我的一个同事,工作一年了,写这段代码的时候,出了错。
他的写法如下
for(inti =0;i < typeList.size();i++) {
if("two".equals(typeList.get(i))) {
typeList.remove(i);
}
}
这段代码暴露的其他问题暂且不提,只说list,
如果是一年前的我,估计也是这样的做法,
然而,工作近两年的我,踩过的坑也不少了,
至少知道了一点:移除list的元素不能用循环,得用迭代器
如下
Iterator iter = list.iterator();
while(iter.hasNext()){
String s = iter.next();
if(s.equals("two")){
iter.remove();
}
}
可是他不懂,为什么这样循环会有问题,于是,我跟他分析了一下(别问我他为什么不懂,鬼知道他为什么不自己想一下)
原因如下
这里如果用循环来移除,会造成遗漏,比如把第0个移除,那么原本list中的的第一个就变成了第0个,这时候,第二次循环中这个元素(现在的第0个,原本的第一个)会被跳过,因为此时i = 1。
他说:我就习惯这样写,这样写能改一下,把坑填上吗?
我稍微思索了一下,可以试试if中增加i=i-1,
类似跳过的还有continue,和跳出的break,至于goto,就不说了,基本用不到
然后我又想起了之前微信群里别人说的,可以倒过来遍历
于是和他分析了一下,为什么倒过来遍历是可以的
因为删除list中的元素,影响的是:被删位置之后的元素的位置,之前的元素位置不会影响,倒着循环,就算删除了一个元素,接下来遍历的是更前面的元素,这些元素没有被移动改变,所以倒着可行。
今天查看LocalBroadcastManager源码,发现了他也在遍历list的时候移除一个item
代码如下:
for(intk=0;k
if(receivers.get(k).receiver== receiver) {
receivers.remove(k);
k--;
}
}
看见这段代码,内心瞬间欣喜
为啥,因为我回想起了我学习C语言(面向过程)的经历,在那段时期,如果类似的代码,我肯定也会这样写,而不会倒着循环,也不会去用迭代器,
为啥,
就因为习惯这样,熟悉这样,喜欢这样
同一段逻辑的不同的代码实现,能表现出来的除了每个人的经验,还有每个人的思维方式。
顺带一提,那时候我应该是大一,只学了C语言,而现在,我用的是java
![](https://img.haomeiwen.com/i1091001/a4a3df1264f33002.jpg)
---------------------------------------------------------------
关注我的微信公众号,里面会有一些我也不知道是啥的东西
![](https://img.haomeiwen.com/i1091001/978eea95db0cbc51.jpg)
网友评论