黑马程序员技术交流社区

标题: 求解答 [打印本页]

作者: 643997890    时间: 2015-9-17 00:35
标题: 求解答
        public static void main(String[] args) {
                // 2、一个ArrayList对象aList中存有若干个字符串元素,现欲遍历该ArrayList对象,删除其中所有值为“abc”的字符串元素,请用代码实现。
                ArrayList<String> aList = new ArrayList<String>();
                aList.add("afdfsdjiabc");
                aList.add("afdslfdsac");
                aList.add("fdsfsdfabc");
                aList.add("fdsfsdfabc");
                for (int i = 0; i < aList.size(); i++) {
                        String s = aList.get(i);
                        if (s.contains("abc")) {
                                aList.remove(i);
                                i--;
                        }
                }
                System.out.println(aList);
        }
我就想知道为什么这里remove删除之后i要--。求解答的自习一点,谢谢了


作者: 水果牛牛    时间: 2015-9-17 00:35
因为你把一个元素从集合中移除的时候,集合的长度会减1,里面的元素所对应的角标也会减1.
举个例子吧,比如说你这个集合长度是5,然后0角标的元素就符合要求,被删除了。这时集合长度
就变为4,原先1角标的元素现在对应的角标为0.也就是说你i=0删除了一个元素后,接下来要检查的元素的角标依然是0。为了保证这个效果,所以在你删除了一个元素后,i先减1,然后在for循环上自增加1,i不变。
作者: Chendamai    时间: 2015-9-17 11:28
删除abc之后 aList后面的字符串会往前移 那么后面的那个字符串就会占据当前的abc的脚标了。。。如果i不 i--的话。。。那么下次i++就不会遍历当前向前移动了的占据abc脚标的这个字符串了
作者: 生存追求    时间: 2015-9-17 15:48
因为集合的长度变小了,如果不i--,下面运行String s = aList.get(i);时会报异常java.lang.IndexOutOfBoundsException
作者: 夸克    时间: 2015-9-17 18:42

      另外如果是删元素,建议用迭代器Iterator,迭代器自身有iterator.remove();方法,而不要用数组的remove方法。就不需要考虑什么加一减一的问题了,
迭代器就帮你做了

作者: xiaoya0o0o    时间: 2015-9-17 22:41
  1. import java.util.ArrayList;
  2. import java.util.List;

  3. public class Test5 {

  4.         /**
  5.          * @param args
  6.          */
  7.         public static void main(String[] args) {
  8. //                5,一个ArrayList对象alist中存有若干个字符串元素,现欲遍历该ArrayList对象,
  9. //                删除其中所有值为"abc"的字符串元素,请问下面的实现正确么?如有问题,
  10. //                会出现什么问题?如何更正?
  11.                
  12.                 //1,移除成功会导致集合长度改变, 必须要重新获取size。导致了IndexOutOfBoundsException。
  13.                 //解决方案:在for循环的条件上,调用size方法。
  14.                 //2,出现了有些abc没有被删除。那么是因为删除后,角标自增,原角标上的后替换过来的元素没有被判断。
  15.                 //解决方案:在删除后,要让角标自减,重新判断替换过来的元素。
  16.                
  17.                 List<String> list = new ArrayList<String>();
  18.                 list.add("nba");
  19.                 list.add("abc");
  20.                 list.add("abc");
  21.                 list.add("abc");
  22.                 list.add("abc");
  23.                 list.add("cctv");

  24.                 System.out.println(list);
  25. //                int size = list.size();
  26.                 for(int i = 0; i < list.size(); i++) {
  27.                   if("abc".equals(list.get(i))) {
  28.                     list.remove(i);//会改变集合的长度。应该重新获取size。
  29.                     i--;
  30.                   }
  31.                 }

  32.                 System.out.println(list);
  33.         }

  34. }
复制代码

作者: 梦龙0201    时间: 2015-9-18 22:32
悬赏这个怎么玩?
作者: Yingwenming    时间: 2015-9-19 10:38
ArrayList.get(0)被你删除掉了,原角标为1的成为角标0,原角标为2的成为角标1。然后你的i不i--,那么接下来是ArrayLIst.get(1),这个值对应的是原角标2。
原角标为1的,直接被跳过了
作者: purgatory    时间: 2015-9-20 19:08
删除了那么i就应该继续判断现在补上来的那个元素,所以i应该不变,但是在循环中i会++,所以减一后让他++后仍然是现在的值
作者: zhaoly    时间: 2015-9-21 01:42
举个例子,假设aList.get(0)被删除后,再次执行判断还得是从aList.get(0),而不能是aList.get(1)。就好比数据结构中,线性表顺序存储中删除一个元素,则后面的元素下标都要减一。因此要i--,不然每删除一次就少判断了一次。
作者: 阿加斯冬季    时间: 2015-9-21 15:34
本来你的aList里面有4个元素,如果你的元素里面包含abc,那么就会触发aList.remove(i),比如remove掉你的第2个元素,那么你原来的第三个元素就会变成第二个,第四个就会变成第三个,你的元素总数就会剩下3个,也就是aList.size() = 3,如果不i--,就会导致最后你的 aList.get(i)超限,程序报错
作者: 643997890    时间: 2015-9-22 15:12
都答的不错,我该采纳谁的呢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2