黑马程序员技术交流社区

标题: 【已解决】迭代器内不能修改集合,不明白。 [打印本页]

作者: hello world    时间: 2012-8-8 12:10
标题: 【已解决】迭代器内不能修改集合,不明白。
本帖最后由 刘向阳 于 2012-8-9 08:44 编辑

今天老师讲集合,只是说不能在迭代器中修改集合,但是我就想知道为什么不能修改呢?谁懂给说下,谢了。这个程序是删除年龄为19的人。
public class Exercise2 {

        public static void main(String[] args) {
//                demo1();
//                demo2();
//                demo3();
//                demo4();
        }

        private static void demo4() {
                List list = new ArrayList();
                list.add(new Person("张三", 19));
                list.add(new Person("李四", 20));
                list.add(new Person("王五", 19));
                list.add(new Person("赵六", 19));
                for (Object obj : list) {
                        Person p = (Person) obj;
                        if (p.getAge() == 19)
                                list.remove(p);                // 增强for循环内部就是使用迭代器, 在使用的过程中不能改变原集合. 由于无法获得迭代器, 所以增强for循环不能操作集合.
                }
        }

        private static void demo3() {
                List list = new ArrayList();
                list.add(new Person("张三", 19));
                list.add(new Person("李四", 20));
                list.add(new Person("王五", 19));
                list.add(new Person("赵六", 19));
                System.out.println(list);
                Iterator iter = list.iterator();
                while (iter.hasNext()) {
                        Person p = (Person) iter.next();
                        if (p.getAge() == 19)
                                iter.remove();                // 在使用迭代器的时候, 不能修改集合中的结构, 如果要删除, 需要使用迭代器的remove()方法
                }
                System.out.println(list);
        }

        private static void demo2() {
                List list = new ArrayList();
                list.add(new Person("张三", 19));
                list.add(new Person("李四", 20));
                list.add(new Person("王五", 19));
                list.add(new Person("赵六", 19));
                System.out.println(list);
                for (int i = 0; i < list.size(); i++) {
                        Person p = (Person) list.get(i);
                        if (p.getAge() == 19)
                                list.remove(i--);        // 删除元素后, 后面的元素会向前移动, 这时我们将指针也向前移动一位
                }
                System.out.println(list);
        }

        private static void demo1() {
                List list = new ArrayList();
                list.add(new Person("张三", 19));
                list.add(new Person("李四", 20));
                list.add(new Person("王五", 19));
                list.add(new Person("赵六", 19));
               
                for (int i = 0; i < list.size(); i++) {
                        Person p = (Person) list.get(i);
                        if (p.getAge() == 19)
                                System.out.println(p.getName());
                }
               
                Iterator iter = list.iterator();
                while (iter.hasNext()) {
                        Person p = (Person) iter.next();
                        if (p.getAge() == 19)
                                System.out.println(p.getName());
                }
               
                for (Object obj : list) {
                        Person p = (Person) obj;
                        if (p.getAge() == 19)
                                System.out.println(p.getName());
                }
        }

}
作者: 郑小杰    时间: 2012-8-8 15:57
增强for循环内部使用了迭代器, 在使用的过程中不能改变原集合.否则就会出现ConcurrentModificationException,这是因为对对象的并发操作造成的,就你写的代码来说,迭代器能操作对象,集合也能操作对像,这两个只能用一个,不然就会有安全隐患,所以下边的代码就用了迭代器的remove方法而不用集合的remove方法


作者: hello world    时间: 2012-8-8 17:31
郑小杰 发表于 2012-8-8 15:57
增强for循环内部使用了迭代器, 在使用的过程中不能改变原集合.否则就会出现ConcurrentModificationExcepti ...

恩,这个我倒是明白,就是我没想通两个并发操作怎么就不行那,有点转牛角尖了,没转出来。这个和多线程还是有区别的啊,这个难道也有什么锁?
作者: 杜佳瑞    时间: 2012-8-9 03:03
刘向阳 发表于 2012-8-8 17:31
恩,这个我倒是明白,就是我没想通两个并发操作怎么就不行那,有点转牛角尖了,没转出来。这个和多线程还 ...

Iterator被创建的时候,建立了一个集合中数据的索引表,这个索引表指向原来的对象,当你用集合操作对原来的对象数量改变的时候,这个索引表的内容不会同步改变,所以迭代器再找下一个元素的时候集合里面数据和表内数据不一致,就会发生混乱。集合是动态的,但迭代器在创建后就不能改变,所以对集合操作不会保证同步问题。而ListIterator的出现有效弥补了这一缺陷(前提是带角标的集合)。
作者: hello world    时间: 2012-8-9 08:43
杜佳瑞 发表于 2012-8-9 03:03
Iterator被创建的时候,建立了一个集合中数据的索引表,这个索引表指向原来的对象,当你用集合操作对原来 ...

恩,明白了 谢了




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