黑马程序员技术交流社区

标题: map集合中元素删除的问题 [打印本页]

作者: yumin    时间: 2015-1-20 02:00
标题: map集合中元素删除的问题
今天在做练习的时候,发现一个问题就是在迭代器里面删除集合元素时map2.remove(key1);报错,而it.remove();//根据键删除        就可以正常工作,remove(key);是集合的方法为什么在程序中会出现报错的问题呢?
  1. public static void getMap2(Map<Integer, String> map1)//获取比较后的集合
  2. {
  3.         Map<Integer, String> map2 =map1;
  4.         Set<Integer> key =map2.keySet();//获取键序列
  5.         Iterator<Integer> it =key.iterator();//迭代器
  6.         while(it.hasNext())//判断
  7.         {
  8.                 Integer key1 =it.next();//获取键
  9.                 if ((key1>50)&&(key1<150))                //比较键在50<key<150时删除元素
  10.                         //map2.remove(key1);//为什么不能使用?这一句报错,没有结果
  11.                         it.remove();//根据键删除                               
  12.         }
  13.         System.out.println("判断后的结果");
  14.         show(map2);//打印结果
  15. }
复制代码






作者: 天堂雨    时间: 2015-1-20 09:32
你可以查看API中关于keySet的说明:“返回此映射中包含的键的 Set 视图。该 set 受映射支持,所以对映射的更改可在此 set 中反映出来,反之亦然。如果对该 set 进行迭代的同时修改了映射(通过迭代器自己的 remove 操作除外),则迭代结果是不确定的。set 支持元素移除,通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作可从映射中移除相应的映射关系。”
就是说在迭代器中你可以使用set集合中的的remove方法和iterator中的remove方法对映射(map集合)进行修改,但是不能在迭代器中用map集合的remove方法修改映射(map集合)。
不知道这么说是否表达清楚了~~~
作者: outsider1020    时间: 2015-1-20 09:47
迭代器只是查询集合中的元素而已
作者: Lscreat    时间: 2015-1-20 10:05
迭代器遍历的时候不能操作集合的增删,不然就会报并发修改异常,你用迭代器操作就没事。用集合操作就会出问题。在遍历的时候修改集合要么都用集合操作,要么都用迭代器操作。
作者: yumin    时间: 2015-1-20 11:07
天堂雨 发表于 2015-1-20 09:32
你可以查看API中关于keySet的说明:“返回此映射中包含的键的 Set 视图。该 set 受映射支持,所以对映射的 ...

O(∩_∩)O谢谢~
作者: yumin    时间: 2015-1-20 11:09
Lscreat 发表于 2015-1-20 10:05
迭代器遍历的时候不能操作集合的增删,不然就会报并发修改异常,你用迭代器操作就没事。用集合操作就会出问 ...

哦哦,理解
作者: ben_vs_cong    时间: 2015-1-20 22:12
这是属于并发异常,就是说,因为迭代器是依赖集合存在的,集合自己做了删除操作,而迭代器没有变化,就会抛异常,这个解决就是,你使用迭代器遍历那么就用迭代器进行操作集合,即要么都用迭代器,要么都用集合。不知道明白没有,视频中会讲解到!
作者: 银离子    时间: 2015-1-21 00:16
yumin 发表于 2015-1-20 11:07
O(∩_∩)O谢谢~

他的倒数第二句是错的,在用迭代器遍历集合时,是不能用集合中的remove()方法操作集合数据的,只能用Iterator中的remove()方法,
作者: yumin    时间: 2015-1-21 02:37
ben_vs_cong 发表于 2015-1-20 22:12
这是属于并发异常,就是说,因为迭代器是依赖集合存在的,集合自己做了删除操作,而迭代器没有变化,就会抛 ...

明白,说得很清楚,谢谢
作者: 梁小刀11    时间: 2015-1-21 21:55
楼上都是大婶
作者: 20150102    时间: 2015-1-22 18:57
还没学集合  来看看
作者: 银离子    时间: 2015-1-23 14:44
本帖最后由 银离子 于 2015-1-23 14:46 编辑
天堂雨 发表于 2015-1-20 09:32
你可以查看API中关于keySet的说明:“返回此映射中包含的键的 Set 视图。该 set 受映射支持,所以对映射的 ...

鄙人不才,请解释如下代码??
  1. import java.util.Iterator;
  2. import java.util.Set;
  3. import java.util.TreeMap;

  4. public class IterText {

  5.         /**
  6.          * @param args
  7.          */
  8.         public static void main(String[] args) {
  9.                 // TODO Auto-generated method stub
  10.                 TreeMap<Integer, String> hm = new TreeMap<Integer, String>();
  11.                 hm.put(55, "a");
  12.                 hm.put(64, "b");
  13.                 hm.put(74, "c");
  14.                 hm.put(85, "d");
  15.                 hm.put(97, "e");

  16.                 Set<Integer> st = hm.keySet();//键集合
  17.                 Iterator<Integer> it = st.iterator();// 迭代器

  18.                 while (it.hasNext()) {
  19.                         int buf = it.next().intValue();
  20.                         if (buf == 74) {
  21.                                 
  22.                                 st.remove(buf);// st集合中的方法,使用此方法抛出java.util.ConcurrentModificationException 异常     请解释??????
  23.                                 // it.remove();//st集合返回的迭代器,此方法不抛异常
  24.                         }

  25.                 }
  26.                 System.out.println(hm.size());

  27.                 Set<Integer> sst = hm.keySet();
  28.                 Iterator<Integer> itt = sst.iterator();// 新迭代器
  29.                 // 打印集合
  30.                 while (itt.hasNext()) {
  31.                         Integer i = itt.next();
  32.                         System.out.println(i + "=" + hm.get(i));

  33.                 }

  34.         }
  35. }
复制代码

作者: 天堂雨    时间: 2015-1-26 17:18
银离子 发表于 2015-1-23 14:44
鄙人不才,请解释如下代码??

好吧,你是大神,受教了~~:handshake 是我误解那里面的意思了,它的意思是得到的set中的方法可以删除map的映射,但是在迭代的过程中只能用迭代器的remove方法。
作者: Mr.JUN    时间: 2015-1-28 22:09
天堂雨 发表于 2015-1-26 17:18
好吧,你是大神,受教了~~ 是我误解那里面的意思了,它的意思是得到的set中的方法可以删除map ...

ListIterator接口吧,可以完成迭代过程中删除数据~~~~iterator就不行了




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