黑马程序员技术交流社区

标题: 关于list集合删除元素的问题 [打印本页]

作者: 陈永波    时间: 2012-6-26 01:10
标题: 关于list集合删除元素的问题
本帖最后由 陈永波 于 2012-6-30 22:16 编辑

题目:定义方法, 接收一个已装入Person对象的List, 删除List中age为20的Person
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Exercise2 {
        public static void main(String[] args) {        
        List list = new ArrayList();
               
        list.add(new Person("小1",21));
        list.add(new Person("小2",22));
        list.add(new Person("小3",20));
        list.add(new Person("小4",20));
               
        for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(p);
                        i--;
        }

        System.out.println(list);
        }
        /*
        for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(i--);
        }
        System.out.println(list);
        }
        */


}

class Person {
        private String name;
        private int age;
        
        public Person() {
        }

        public Person(String name, int age) {
                this.name = name;
                this.age = age;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

        public String toString() {
                return "Person [name=" + name + ", age=" + age + "]";
        }        
}

问题:红色部分是正确代码,蓝色部分是错误代码.为什么删除P对象 remove(p),i--;不可以呢,而是需要remove(i--);?最好详细回答  蓝色的代码貌似会出现死循环
作者: 孔肖    时间: 2012-6-26 01:27
其实你就是少了括号
蓝色代码:
for(int i = 0; i < list.size(); i++){
                 Person p  = (Person)list.get(i);
                 if(p.getAge()==20){
                         list.remove(p);
                         i--;//i--应该在移除后减一吧  不加{}就是循环一次减一
                  }
         }
作者: 李伟    时间: 2012-6-26 01:55
  for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                list.remove(i--);//因为list.remove(i--)和list.remove(p)是不同的,
                        //remove(int index) 是移除此列表中指定位置上的元素,
                         //而remove(Object o) 是移除此列表中首次出现的指定元素(如果存在),也就是说如果需要删除的元素有多个,这个方法只能删一个。
                       //所以应该用list.remove(i--)
   
    }
        System.out.println(list);
        }

作者: 周兴中    时间: 2012-6-26 02:14
  for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(p);
                        i--; //i--应该放在if语句内,否则无论是否查找到年龄为20的学生,都将会一直在list.get(0),死循环;
        }

作者: Forever。    时间: 2012-6-26 09:17
本帖最后由 Forever。 于 2012-6-26 09:23 编辑

for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(p);
                        i--;
        }
你的死循环确实是因为这里的i--;
但是我理解你的思路是正确的只不过你忽略了一个极为细小的问题——————大括号;
试一下下面的代码相信你会明白粗心这个东西有多么的可怕:

public static void main(String[] args) {        
        List list = new ArrayList();
               
        list.add(new Person("小1",21));
        list.add(new Person("小2",22));
        list.add(new Person("小3",20));
        list.add(new Person("小4",20));
        
        for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20){
                        list.remove(p);
                        i--;
                }
        }
        System.out.println(list);
        }

运行完毕结果:[Person [name=小1, age=21], Person [name=小2, age=22]]   


事实上你的后面红字的方法是一个道理,因为你remove后list中减少了一个元素,所以for循环将在remove第一次(如果没有i--)的时候退出,而第二个age等于20的person就不会被察觉。

之所以用i--,是因为i--是先运行i的值然后再减1;所你如果你换成--i,就会出现错误的结果,这也是细节






作者: 游洪波    时间: 2012-6-26 10:01
本帖最后由 游洪波 于 2012-6-26 10:02 编辑

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Exercise2 {
        public static void main(String[] args) {        
        List list = new ArrayList();
               
        list.add(new Person("小1",21));
        list.add(new Person("小2",22));
        list.add(new Person("小3",20));
        list.add(new Person("小4",20));
               
        for(int i = 0; i < list.size(); i++){//你这里进入死循环的原因是你没有把i--放入if分支中。你现在看下运行过程,首先每做一次for循环都要将i+1
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(p);//如果if满足的话他会执行这条语句,
                        i--;// 这个i--由于没有放入if分支中所以不管if条件成立与否都会执行,那么这样一来for语句中i+1,到了这边又i-1你想想i的值是不是一直停在了原点啊,所以造成了死循环,
        }
改正后:
        for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20){
                        list.remove(p);
                        i--;//只需要把i--放入if中来就可以了这样的话当if满足的时候他才会执行,不满足的话就不执行,这样就不会进入死循环了
                 }
        }
我这里把API中List和ArrayList中的所以关于remove的方法摘要给你贴了上来
list中的

list中有remove(int intdex )方法但是没有remove(Object o)这个方法
但是在Arraylist这个list的实现类中却有

我想应该能帮到你把!

        System.out.println(list);
        }
        /*
        for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(i--);
        }
        System.out.println(list);
        }
        */


}

class Person {
        private String name;
        private int age;
        
        public Person() {
        }

        public Person(String name, int age) {
                this.name = name;
                this.age = age;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

        public String toString() {
                return "Person [name=" + name + ", age=" + age + "]";
        }        
}

2.JPG (24.83 KB, 下载次数: 84)

2.JPG

2.JPG (24.83 KB, 下载次数: 65)

2.JPG

作者: 黄昆    时间: 2012-6-26 10:51
for(int i = 0; i < list.size(); i++){
                Person p  = (Person)list.get(i);
                if(p.getAge()==20)
                        list.remove(p);//if语句如果不加{},就会默认下一条语句为if要执行的语句,而此时i--;就变成了for语句的循环体了,你先i--,然后又i++就会出现死循环了呀。
//使用remove方法要注意参数,remove(Object obj);是删除列表中首次出现的指定对象,remove(int index);删除列表中指定位置上的元素。
                        i--;
        }





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