List中存储的对象,移除以后,会有什么现象,请解释? 50

 我来答
在晴天的雨伞
2016-05-30 · TA获得超过6869个赞
知道大有可为答主
回答量:5761
采纳率:86%
帮助的人:1217万
展开全部
这个问题看似好像挺简单挺幼稚的,然而就这个幼稚的问题还曾经困扰过我一阵呢,其实犯这个错误的根本原因是我们对于基础知识的理解和掌握上还有不足的表现,基本功有些人总是觉得不重要,认为更多的扩大学习的广度才是最重要的,我认为这是很容易犯的,同时也是很致命的错误观点!
对基础知识掌握不牢靠,或理解不深刻,写出的代码必然会有40%的概率是错误的、低效的,一段代码不是说没有编译错误就一定是对的,不是说简单的运行下就一定是对的,优秀的代码,是经得起“刀山火海”般的考验的(“多线程、效率、安全”这三坐大山)。
所以重要性,我就不再强调了,相信说完后,地球人都能懂我的意思,那么下面就来看看这个有趣的现象吧。

先看看如下代码

[java] view plain copy
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TestList {

void init(List<Integer> list) {
list.clear();
for (int i = 0; i < 10; i++) {
list.add(i + 1);
}
}

void remove(List<Integer> list) {
for (int i = 0; i < 5; i++) {
list.remove(i);
}
}

void removeTwo(List<Integer> list) {
for (int i : list) {
if (i < 6) {
list.remove(i);
}
}
}

void removeThree(List<Integer> list) {
for (Iterator<Integer> iter = list.iterator(); iter.hasNext();) {
int i = iter.next();
if (i < 6) {
iter.remove();
}
}
}

public static void main(String[] args) {
TestList testList = new TestList();
List<Integer> list = new ArrayList<Integer>();

// 第一种方法
testList.init(list);
testList.remove(list);
System.out.println(list);

// 第二种方法
try {
testList.init(list);
testList.removeTwo(list);
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
}

// 第三种方法
testList.init(list);
testList.removeThree(list);
System.out.println(list);
}
}
运行的结果如下:
[2, 4, 6, 8, 10]
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at com.TestList.removeTwo(TestList.java:23)
at com.TestList.main(TestList.java:60)
[6, 7, 8, 9, 10]

上面代码逻辑很简单,就是将List集合里的前5个对象删除掉,然而结果却是相当不一样:第一个是错误的结果,第二个直接报异常,只有第三个是我们想要的结果!

那么这是为什么呢?其实主要原因来自于List中的remove()方法。我们来分析一下:
第一种方法:
第一次执行完remove方法后,并不像我们简单想象的那样就把第一个删除了,“1”这个对象被删除了没错,但是当被删除后List中“2”以后的9个对象的index索引也变了,都比原来的值减一,换句话说就是剩下的9个对象的index值为从0到8,而不是原来的从1到9了,那么第二次执行remove方法时,此时list.remove(1)删除的就是“3”这个对象(“3”的index值为1),而不是我们想象的删除“2”对象。
第二种方法:
原因跟上面一样,导致List的next()方法内部出现modCount和expectedModCount不一致导致抛出异常。

所以我们这里建议大家采用第三种方法来删除List集合中某一个对象,这样做是最简单且容易记忆的。那第一种方法和第二种方法有没有解决的办法呢?目前我知道第一种方法的解决办法,第二种应该是无解的(因为语法结构导致)。

第一种方法的改进措施:

[java] view plain copy
void remove(List<Integer> list) {
int num = list.size() - 5;
for (int i = 0; i < num; i++) {
list.remove(i);
i--;
num--;
}
}
追问
我想要的是语言描述而不是实例
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
九哥666
2016-05-30
知道答主
回答量:9
采纳率:0%
帮助的人:3.2万
展开全部
抱歉数据库的东西真没有玩过,我知识路过。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式