今天在写程序过程中,需要根据判断条件删除一个Map中的相应数据,我自然而然想到可以通过调用Map中的remove(Object key)函数进行删除:代码如下:

public Map<Double, Double> processMap(Map<Double, Double> list) {

Map<Double, Double> map = list;

Iterator<Double> iter = map.keyset().iterator;

while(iter.hasNext()) {

double key = iter.next();

if (key > 5)

map.remove(key);

}

return map;

}

但是运行程序的时候却没有正常删除元素,而是提示“Java.util.ConcurrentModificationException”错误,很是疑惑,于

是找了一些关于Map的资料发现:Map的实现不是同步的。如果程序中出现多个线程同时访问一个Map,而其中至少一个线程修改Map

时,它必须保持外部同步。而通过查看Iterator原理发现,Iterator是工作在一个独立的线程中,并且拥有一个 mutex锁,就是说

Iterator在工作的时候,是不允许被迭代的对象被改变的,所以调用Iterator操作获得的对象在多线程修改Map的时候会自动失效。

Iterator被创建的时候,建立了一个内存索引表(单链表),这 个索引表指向原来的对象,当原来的对象数量改变的时候,这个索

引表的内容没有同步改变,所以当索引指针往下移动的时候,便找不到要迭代的对象,于是产生错 误。Map、List、Set等是动态

的,可变对象数量的数据结构,但是Iterator则是单向不可变,只能顺序读取,不能逆序操作的数据结构,当 Iterator指向的原始

数据发生变化时,Iterator自己就迷失了方向。

既然找到了问题的原因,那么如何解决呢?可以通过调用Iterator的remove(Object o)函数来移除元素。

测试代码如下:

public Map<Double, Double> processMap(Map<Double, Double> list) {

Map<Double, Double> map = list;

Iterator<Double> iter = map.keyset().iterator;

while(iter.hasNext()) {

double key = iter.next();

if (key > 5) {

//   map.remove(key);  // java.util.ConcurrentModificationException

iter.remove(key);  // OK

}

}

return map;

}

同时,在遍历Map过程中,调用put(key, value)函数来添加元素,也会出现同样的问题,所以同样需要使用迭代器的相应函数来添加。

Java根据条件删除Map中元素的更多相关文章

  1. js删除map中元素

    js中删除map中元素后,map的长度不变,这时需要我们自己处理 delete vacc[0]; delete vacc[1]; ClearNullArr(vacc); //清除vacc中的null值 ...

  2. JAVA中循环删除list中元素的方法总结【转】

    印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...

  3. java中循环删除list中元素的方法

    重点哈 印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接 ...

  4. 【方法1】删除Map中Value反复的记录,而且仅仅保留Key最小的那条记录

    介绍 晚上无聊的时候,我做了一个測试题,測试题的大体意思是:删除Map中Value反复的记录,而且仅仅保留Key最小的那条记录. 比如: I have a map with duplicate val ...

  5. python删除列表中元素的方法

    删除列表中元素的三种方法-remove.pop.del 1 1.remove: 删除单个元素,删除首个符合条件的元素,按值删除 2 举例说明: 3 >>> str=[1,2,3,4, ...

  6. python中循环删除列表中元素时的坑!

    循环删除列表中元素时千万别用正序遍历,一定要用反序遍历! 废话不多说,先上案例代码: def test(data): for i in data: data.remove(i) return data ...

  7. js删除数组中元素 delete 和splice的区别

    例如我有一个数组: var array = ["aa","dd","cc","aa"] ,我想删除这个数组的“dd”元素 ...

  8. js删除数组中元素的方法

    一.清空数组 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即被清空了 二.删 ...

  9. dtgrid 手动条件删除表格中的某一行

    dtgrid 手动条件删除表格中的某一行 var grid = $.fn.DtGrid.init(dtGridOption); $(function () { grid.load(); }); fun ...

随机推荐

  1. Python学习总结2:raw_input() 与 input()

    参考http://www.cnblogs.com/way_testlife/archive/2011/03/29/1999283.html 1. 输入数据要求 raw_input() 直接读取控制台的 ...

  2. poj: 2739

    挺简单,生成素数表之后建个全素数的vector,然后..随便玩咯 #include <iostream> #include <stdio.h> #include <str ...

  3. javascript语法详解

    javascript语法:运算符 条件语句if...else...  条件语句switch  循环语句for  循环语句while   跳转语句 js运算符 1.算数运算符:+ - * % / ++ ...

  4. SQL Server面试题

    前几天在博客园上看到一道SQL面试题,sc是表名.老师拿来与同学分享,让大家试做,要求是:查出每科成绩都>=80分的名字,看能写出几种方法.没有主外键,没有关联,脑袋一下子就蒙了.经老师讲解指导 ...

  5. strcpy  复制字符串函数

    #include<stdio.h> #include<assert.h> char *strcopy(char * strDest , const char * strSrc) ...

  6. 自定义view(使用EditTetx实现记事本特效)

    先看一下效果图: 思路: 创建一个类,继承自EditText,在onDraw方法中绘制我们的下划线,通过屏幕的高度和每行控件的高度的比值得出屏幕中应该绘制多少行下划线,再来实现一些自定义的属性,设置控 ...

  7. paper 28 :一些常见常用数据库的下载网站集锦

    做图像处理+模式识别的童鞋怎么可以没有数据库呢? 但是,如果自己做一个数据库,费时费力费钱先不说,关键是建立的数据库的公信力一般不会高,做出的算法也别人也不好比较,所以呢,下载比较权威的公共数据库还是 ...

  8. jquery stop

    stop():停止当前活动的动画,但允许已排队的动画向前执行 stop(true):停止当前活动的动画,并清空动画队列:因此元素上的所有动画都会停止 stop(true,true):会立即完成当前活动 ...

  9. linux-批量重命名脚本

    #!/bin/bash # rename jpg and png count= for img in *.jpg *.png do new=image-$count.${img#*.} mv > ...

  10. 夺命雷公狗---DEDECMS----18dedecms之无可奈何标签-sql标签取出今天更新

    我们在一些开发时候遇到普通标签都解决不了的问题的时候可以尝试下我们dedecms自带的sql标签,几乎可以完成任何的查询需求 语法如下所示: 我们在这里将刚才首页今天更新那块给改写下,原先的是: {d ...