黑马程序员技术交流社区

标题: for循环里,if和while的区别,为什么会出现这样的情况 [打印本页]

作者: 创意三千取其一    时间: 2015-11-25 15:56
标题: for循环里,if和while的区别,为什么会出现这样的情况
本帖最后由 创意三千取其一 于 2015-11-25 15:58 编辑

public class Demo11 {
        public static void main(String[] args){
                List<String> alist=new ArrayList<String>();
                alist.add("神盾局特工");
                alist.add("福尔摩斯基本演绎法");
                alist.add("生活大爆炸");
                alist.add("abc");
                alist.add("abc");
                alist.add("abc");
                alist.add("abc");
                alist.add("lie to me");
                System.out.println(alist);
                for(int i=0;i<alist.size();i++){
                        if(alist.get(i).equals("abc")){
                                alist.remove(i);
                        }
                }
                System.out.println(alist);
        }
}
输出:[神盾局特工, 福尔摩斯基本演绎法, 生活大爆炸, abc, abc, lie to me]
add添加了四个“abc”,但是remove只去掉了两个。打印后还显示了两个。
————————————————————————————————————————————————————————————————————
我把上面代码中for循环里面的if语句换成while之后:
                for(int i=0;i<alist.size();i++){
                        while(alist.get(i).equals("abc")){
                                alist.remove(i);
                        }
                }

编译输出:[神盾局特工, 福尔摩斯基本演绎法, 生活大爆炸, lie to me]
一切正常,所有的“abc”都去掉了。
其他代码都没有改动,只是把if换为while,就达到预想的目的了。
请高手指点迷津,谢谢!



作者: hdhunter    时间: 2015-11-25 16:00
路过。刷一下。
作者: 一江夜雨    时间: 2015-11-25 17:04
  for(int i=0;i<alist.size();i++){
                        if(alist.get(i).equals("abc")){
                                alist.remove(i);
                                 i--;
                        }
                }
你试试这样就行了     因为你每次移除“abc”的时候,集合的size()是在变化的,不是不变的。  减去一个“abc”,集合的size也在相应变小,size的变化是随着“i”变化的,所以我们需要把“i”也相应减去一个。

作者: 创意三千取其一    时间: 2015-11-25 17:49
一江夜雨 发表于 2015-11-25 17:04
for(int i=0;i

果然,但是为什么while可以的?
作者: 创意三千取其一    时间: 2015-11-25 18:00
本帖最后由 创意三千取其一 于 2015-11-25 18:03 编辑
一江夜雨 发表于 2015-11-25 17:04
for(int i=0;i

我试了一下,
有2个和3个连续的alist.add("abc")时,只打印1个,
有4个和5个连的alist.add("abc")时,打印2个,
有6个和7个连续的alist.add("abc")时,打印3个,
如果按size长度变小解释,就都解释通了。
不过while那个为什么可以还不知道,而且在while里加上i--也没问题。




作者: ClimberRobert    时间: 2015-11-25 18:16
本帖最后由 ClimberRobert 于 2015-11-25 18:18 编辑

当i==3时,alist.get(i).equals("abc")成立,while中的alist.remove(i)语句会不断执行,每执行一次原来索引为3的abc被删除,后面的元素一次往前移动一次,alist.get(i).equals("abc")仍然成立,while语句会不断自循环,直到所有的abc都被删除完。
而如果是if,每次循环其实包含了3个操作:(1)索引为i的被移除;(2)索引为i+1以及之后的元素,索引都-1;(3)i++ ; 循环一次后,i就自加了,再次执行if语句的时候删除的是索引为4 的元素,索引原先为4的元素因为移动到3的位置,所以保留了下来。

你可以做一个实验,将4个abc依次变为abc1,abc2,abc3,abc4;然后将判断条件改为alist.get(i).startWith("abc"),你会发现abc1,abc3被删除,abc2,abc4保留了下来。

作者: 梦想家Eva    时间: 2015-11-25 18:27
一江夜雨 发表于 2015-11-25 17:04
for(int i=0;i

这样子啊,长见识了,顺便问下为什么while循环可以成功删除啊?
作者: 一江夜雨    时间: 2015-11-25 18:54
创意三千取其一 发表于 2015-11-25 18:00
我试了一下,
有2个和3个连续的alist.add("abc")时,只打印1个,
有4个和5个连的alist.add("abc")时,打印 ...

你自己列一下就看出来了  此题,其实while里面相当于隐藏了一个“i--”  反正数目也不多   下面的那个climberRobert已经给你解答了
作者: bukai123    时间: 2015-11-26 09:29
删除的时候后面的角标向前进一,删掉1的时候,2就到了1的位置,3到了2的位子,3就被删除了,4到2的位子,保留
作者: Evelyn_Jone    时间: 2015-11-27 21:01
梦想家Eva 发表于 2015-11-25 18:27
这样子啊,长见识了,顺便问下为什么while循环可以成功删除啊?

因为当你进行while循环的时候,满足条件后会进行删除,此时i相当于是之前的值,肯定不会匹配你要的值,自然就不会进入while循环,然后i++进行下一个判断,同理
作者: xiaoniu706    时间: 2015-11-27 21:18
乱顶顶顶
作者: liuqiang11164    时间: 2015-11-27 21:36
用try。。catch试试
作者: hansnowqiang    时间: 2015-11-27 21:52
本帖最后由 hansnowqiang 于 2015-11-27 22:04 编辑

Arraylist读写类似于栈,当你对他进行操作时会类似弹栈:
(0)神盾局特工                   0
(1)福尔摩斯基本演绎法     1
(2)生活大爆炸                   2
(3)abc                              3
(4)abc                              4
(5)abc                              5
(6)abc                              6
(7)lie  to me                    7
当for循环3时if语句判断移除了3号位的(3)abc   4号位的(4)abc   自动上弹一位,后面的也随着上弹一位。
(0)神盾局特工                   0
(1)福尔摩斯基本演绎法     1
(2)生活大爆炸                   2
(4)abc                              3
(5)abc                              4
(6)abc                              5
(7)lie  to me                    6

这时for循环走4,去除了4号位上的(5)abc  ,后面的5号位上的(6)abc   自动上弹一位,后面的也随着上弹:
(0)神盾局特工                   0
(1)福尔摩斯基本演绎法     1
(2)生活大爆炸                   2
(4)abc                              3
(6)abc                              4
(7)lie  to me                    5
最终结果就如上面.。

当你使用while:
for循环走3时,while循环判断条件为alist.get(3).equals("abc"),去除掉了(3)abc   这时while循环并没有结束依然在继续。
for循环依然为3,则while循环的条件依然为alist.get(3).equals("abc"),但这时(4)abc  已经上弹到了3的位置,去掉了(4)abc ,这时while循环还在继续
如此循环,去掉了所有的abc。当while循环运行到lie to me 时。不符合条件循环结束。







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