黑马程序员技术交流社区

标题: 关于并发修改异常的一个问题 [打印本页]

作者: ID1003    时间: 2014-5-18 20:52
标题: 关于并发修改异常的一个问题
本帖最后由 ID1003 于 2014-5-19 21:08 编辑

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ListTest {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                List list=new ArrayList();
                list.add("hello");
                list.add("world");
                list.add("java");
                ListIterator it = list.listIterator();
                while (it.hasNext()) {
                        String s=(String)it.next();
                        if (list.contains("hello")) {
                                it.add("aaa");
                        }
                }
                /*while (it.hasNext()) {
                        String s=(String)it.next();
                        if (list.contains("hello")) {
                                list.add("aaa");
                        }
                }*/
                //注释这里就是发生并发修改异常的代码
               
                System.out.println(list);
                System.out.println("----------");
                for (int i = 0; i < list.size(); i++) {
                        String s=(String)list.get(i);
                        if (s.equals("hello")) {
                                list.add("bbb");
                        }
                        System.out.print(s+" ");
                }
        }
}




老师说上面两种方法都可以解决并发修改异常的问题,但是我测试了一下之后运行结果是
[hello, aaa, world, aaa, java, aaa]
----------
hello aaa world aaa java aaa bbb
可以看得出来第一种方法是把每个字符串后面都增加了一个aaa字符串,而第二种只是在末尾处增加了一个,想不明白为什么。
作者: 张百振    时间: 2014-5-18 21:30
     首先你先看一。boolean contains(Object o)如果列表包含指定的元素,则返回 true。更确切地讲,当且仅当列表包含满足 (o==null ? e==null : o.equals(e)) 的元素 e 时才返回 true。 指定者:接口 Collection<E> 中的 contains参数:o - 要测试列表中是否存在的元素 返回:如果列表包含指定的元素,则返回 true所以你在拿到迭代器遍历的时候调用list.contains("hello");判断当前集合是否包含元素hello,所以list.contains("hello")这个判断一直都是true,所以在你遍历的时候,没判断一次都会为当前集合添加一次“add”。所以呢你改成while (it.hasNext()) {
                        String s=(String)it.next();
                        if (s.euqals("hello")) {
                                list.add("aaa");
具体代码如下:import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ListTest {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                List list=new ArrayList();
                list.add("hello");
                list.add("world");
                list.add("java");
                ListIterator it = list.listIterator();
                while (it.hasNext()) {
                        String s=(String)it.next();
                        if (s.equals("hello")) {
                                it.add("aaa");
                        }
                }
                /*while (it.hasNext()) {
                        String s=(String)it.next();
                        if (list.contains("hello")) {
                                list.add("aaa");
                        }
                }*/
                //注释这里就是发生并发修改异常的代码
               
                System.out.println(list);
                System.out.println("----------");
                for (int i = 0; i < list.size(); i++) {
                        String s=(String)list.get(i);
                        if (s.equals("hello")) {
                                list.add("bbb");
                        }
                        System.out.print(s+" ");
                }
        }
}
        就只会在hello之后添加一个元素了,String类的equals()已经重写了,它比较的是字符串是否相等,所以只有当迭代器拿到“hello“元素的时候判断条件才为真,才会添加到集合”add“的,现在明白了吧?




作者: 帅哥哥    时间: 2014-5-18 21:53
楼主是散财童子的说~~~(ps:先抢楼,待编辑~~~)

作者: 流沙    时间: 2014-5-18 22:12
这个要顶一下
作者: skill20    时间: 2014-5-18 22:33
对集合用一般的迭代器迭代时,用集合的方法对集合中的数据进行增删都会有异常。
最好就是用特有迭代器来完成。
ps:楼主的Eclipse怎么在方法上自动加上注释的?
作者: ID1003    时间: 2014-5-18 23:59
:'(强烈鄙视你们那些只拿黑马币不回复正经问题的人




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