日期:2014-05-20  浏览次数:20770 次

关于Java 集合List的问题
package First_MaShiBing;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
public static void main(String[] args) {

List<String> list = new ArrayList<String>();
list.add("王莹");
list.add("朱仁怡");
list.add("刘大勇");
list.add("王志彪");
list.add("王进喜");
list.add("王玉兰");

//分别调用下面三个方法:


}

/**
* 第一种方法,
* 删除时总会少删一个。
* @param list
*/
public static void userForeach(List<String> list){
for(String string : list)
if(string.indexOf("王") != -1)
list.remove(string);
for(String string:list)
System.out.println(string);
}

/**
* 第二种方法,
* 报异常无法执行。
* @param list
*/
public static void userFor(List<String> list){
for(int i =0; i < list.size(); i++)
if(list.get(i).indexOf("王") != -1)
list.remove(i);
for(String string:list)
System.out.println(string);
}

/**
* 第三种方法,
* 执行成功;
* @param list
*/
public static void userIter(List<String> list){
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
if (iterator.next().indexOf("马") != -1) {
iterator.remove();
}
}
for(String string:list)
System.out.println(string);
}

}

问题:其中的三个方法执行结果为什么会有这样的差异,其中是怎么个原理。请大侠指点?

------解决方案--------------------
你第一种和第二种的注释写反了。
首先
Java code

for(String string:list)
    System.out.println(string);

------解决方案--------------------
userForeach方法
for(String string : list)对list进行迭代的时候,不允许修改list。
按常理想想,就像一个队伍有十个人,正在从第一个人到第十个人报数,报到第五个人了,这时把第三个人抽走了,那这个数还怎么报了?往下第六个还是第六个吗?这就乱了。for循环是不允许有这种中途改变list的情况发生的。如果发生,将抛出异常。

userFor方法
这也很好理解。原来王志彪是第3个位置,当被remove的时候,王进喜变成了第3个位置,王玉兰变成了第四个位置。这时,i自加1,取得第四个位置就是王玉兰,王志彪就没有被循环到。要正确删除,if语句里就应该加一个 i--;

一般正常的方法就是楼主的第三种方法userIter,就可以了。iterator会处理上面遇到的情况。
------解决方案--------------------
技术支持也是这么想的。

同1、2楼看法一致。

不过说点的是:ArrayList是基于数组实现的,所以楼主再想想?
数据结构。。。。

记得给分呀。^_^
------解决方案--------------------
探讨

userForeach方法
for(String string : list)对list进行迭代的时候,不允许修改list。
按常理想想,就像一个队伍有十个人,正在从第一个人到第十个人报数,报到第五个人了,这时把第三个人抽走了,那这个数还怎么报了?往下第六个还是第六个吗?这就乱了。for循环是不允许有这种中途改变list的情况发生的。如果发生,将抛出异常。

userFor方法
这也很……

------解决方案--------------------
其实就是foreach 在迭代的时候不允许修改,至于for循环,就很简单了,二楼说的很好
------解决方案--------------------
用迭代器修改元素前必须确认你的list类型支持这种修改,事实上有些list或set是不支持这种修改的,他们的迭代器可能不锁定资源,当然也不会抛出快速失败异常
------解决方案--------------------
方法一修改了下
Java code



    public static void userForeach(List<String> list){
        List<String> temp = new ArrayList<String>();
        for(String str : list) {
            if(str.indexOf("王") != -1) {
                temp.add(str);
            }
        }
        list.removeAll(temp);
        for(String string:list) {
            System.out.println(string);
        }
    }

------解决方案--------------------
结贴就可以给分了
------解决方案--------------------
集合中根据索引移除一个对象建议使用迭代器Iterator,