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);
}}问题:其中的三个方法执行结果为什么会有这样的差异,其中是怎么个原理。请大侠指点?

解决方案 »

  1.   

    你第一种和第二种的注释写反了。
      首先
    for(String string:list)
    System.out.println(string);foreach 不允许增删操作  因为foreach在迭代遍历的时候建立了一张表来查询,具体百度public static void userFor(List<String> list){
    for(int i =0; i < list.size(); ){
    System.out.println("--"+list.get(i));
    if(list.get(i).indexOf("王")!= -1)
    list.remove(i);
    else
    i++;
    }
    for(String string:list)
    System.out.println(string);
    }你删掉i,然后后面的向前移一个索引 然后你i++,跳过了。
      

  2.   

    userForeach方法
    for(String string : list)对list进行迭代的时候,不允许修改list。
    按常理想想,就像一个队伍有十个人,正在从第一个人到第十个人报数,报到第五个人了,这时把第三个人抽走了,那这个数还怎么报了?往下第六个还是第六个吗?这就乱了。for循环是不允许有这种中途改变list的情况发生的。如果发生,将抛出异常。userFor方法
    这也很好理解。原来王志彪是第3个位置,当被remove的时候,王进喜变成了第3个位置,王玉兰变成了第四个位置。这时,i自加1,取得第四个位置就是王玉兰,王志彪就没有被循环到。要正确删除,if语句里就应该加一个 i--;一般正常的方法就是楼主的第三种方法userIter,就可以了。iterator会处理上面遇到的情况。
      

  3.   

    技术支持也是这么想的。同1、2楼看法一致。不过说点的是:ArrayList是基于数组实现的,所以楼主再想想?
    数据结构。记得给分呀。^_^
      

  4.   

    其实就是foreach 在迭代的时候不允许修改,至于for循环,就很简单了,二楼说的很好
      

  5.   

    循环什么场合用 iterator 什么场合用 foreach ?高手请指教
      

  6.   

    用迭代器修改元素前必须确认你的list类型支持这种修改,事实上有些list或set是不支持这种修改的,他们的迭代器可能不锁定资源,当然也不会抛出快速失败异常
      

  7.   

    方法一修改了下 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);
    }
    }
    方法二也给你修改了下 public static void userFor(List<String> list){
    for(int i = list.size() - 1; i >= 0; i--) {
    if(list.get(i).indexOf("王") != -1) {
    list.remove(i);
    }
    }
    for(String string:list) {
    System.out.println(string);
    }
    }这2个方法应该也会是正确的结果了
      

  8.   

    集合中根据索引移除一个对象建议使用迭代器Iterator,
    使用  for(int i =0; i < list.size(); )循环移除因为移除后集合个数已经改变了,所以移除就会产生问题,非要用这个也可以,要为后面加个i--;
    回答完毕!