黑马程序员技术交流社区

标题: 高级 for 时的疑惑 [打印本页]

作者: 余善航    时间: 2013-2-22 20:08
标题: 高级 for 时的疑惑
package System_1;

import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

public class System_01 {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub

                Properties p=System.getProperties();
                Set st=p.keySet();
                Iterator it=st.iterator();
                System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); //?
                /*for(Object o : p.keySet())
                {
                        String key=(String)o;
                        String value=System.getProperty(key);
                        System.out.println(key+"  "+value);
                }*/
               
                while(it.hasNext())
                {
                        String key=(String)it.next();
                        String value=(String)p.getProperty(key);
                        System.out.println(key+"  "+value);
                }
               
               
        }

}
/*
* 当System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");用高级for输出时,
*         不出异常
*  而用Iterator遍历输出时,就出异常  为什么
*/
作者: 许鑫星    时间: 2013-2-22 21:18
因为在set的迭代器获取了之后你用System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");又往集合中加了元素,所以当前集合的迭代器已经被修改了,不能在用原来的迭代器迭代,解决的话,在你设置了新的属性之后再获取集合的迭代器就行了。
作者: 顾传文    时间: 2013-2-22 21:38
在用Iterator迭代Collection集合的时候,同时使用集合的方法操作存在安全隐患,会发生ConcurrentModificationException异常。
但是Iterator的方法比较少,只能对元素进行判断,取出和删除的操作;为了方便操作,如:添加、修改等就增加了子接口ListIterator,ListIterator是List集合体系特有的迭代器。
Properties是Map集合,一般使用EntrySet或KeySet来迭代。而这两种都是set集合,这里就不能使用ListIterator来实现了。
解决方法一:将下面“Iterator it=st.iterator();”代码写到System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 后面。
解决方法二:使用for循环。
作者: 吴硕    时间: 2013-2-22 21:41
本帖最后由 吴硕 于 2013-2-22 21:44 编辑

问题并不是出在高级for上
集合在迭代过程中,不能再修改集合,否则会引发ConcurrentModificationException异常。
迭代集合最好使用如下的方式,可以及时释放内存,代码也更紧凑
  1. for(Iterator it = st.iterator(); it.hasNext();)
  2. {
  3.         String key=(String)it.next();
  4.         String value=(String)p.getProperty(key);
  5.         System.out.println(key+"  "+value);
  6. }
复制代码

作者: 偏執旳、靑春    时间: 2013-2-22 21:45
  1. package cn.test;
  2. import java.util.Iterator;
  3. import java.util.Properties;
  4. import java.util.Set;

  5. public class Test {

  6.         /**
  7.          * @param args
  8.          */
  9.         public static void main(String[] args) {
  10.                 // TODO Auto-generated method stub

  11.                 Properties p=System.getProperties();
  12.                 Set st=p.keySet();
  13.                
  14.                 System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); //?
  15.                 Iterator<String> it=st.iterator();
  16.                 /*for(Object o : st)
  17.                 {
  18.                         String key=(String)o;
  19.                         String value=System.getProperty(key);
  20.                         System.out.println(key+"  "+value);
  21.                 }*/
  22.                
  23.            while(it.hasNext())
  24.                 {
  25.                         //String key = (String)it.next();
  26.                         //String value=(String)p.getProperty(key);
  27.                        //System.out.println(key+"  "+value);
  28.                        
  29.                System.out.println(it.next());
  30.                
  31.                 }
  32.                
  33.         }

  34. }
复制代码
你再试试看!迭代器产生后,就不要进行增删操作了,只能查了
作者: 胥文    时间: 2013-2-22 22:00
本帖最后由 胥文 于 2013-2-22 22:02 编辑

Iterator it=st.iterator();//这里在从集合中取
System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); //这里往集合里面添加
这样就会导致修改并发异常
你将这两句话互换一下位置就好了
其实你的高级for也不行,如果像下面这么写就会并发异常
而你的迭代其实就类似的像下面这么写的,而你非要在迭代里面加System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
Iterator it=st.iterator();//迭代的这句话和下面的循环就像for循环是个整体,你在里面调用System.setProperty("aaaaaaa","saaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 就会报异常
while()
{

}
for(Object s1:s)
{        
        p.setProperty("123", "abc");//这样也是不行的哦,和上面是一个原因
        System.out.println(s1);
}

作者: 谢玉成    时间: 2013-2-22 22:32
赞同前几楼的...
   但还是说说我个人理解吧,因为Iterator迭代器是每个集合内部都有一个,而且都是自己在自己内部实现的,当你获取到了该集合的迭代器后,再在迭代器后面对原来的集合进行操作,那么在该迭代器后面对原集合操作的元素,可以说迭代器‘不认识',从而导致了ConcurrentModificationException(并发修改异常)的抛出,所以在获取了集合的迭代器后不要对原集合进行操作,(ArrayList集合除外,因为它除了有Iterator迭代器外,自己有一个特有的迭代器),否则要使用其他的方法遍历集合.
    以上是个人理解,如果理解不对请大伙拍砖....{:soso_e129:}




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