今天在写程序过程中,需要根据判断条件删除一个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. poj 题目分类(1)

    poj 题目分类 按照ac的代码长度分类(主要参考最短代码和自己写的代码) 短代码:0.01K--0.50K:中短代码:0.51K--1.00K:中等代码量:1.01K--2.00K:长代码:2.01 ...

  2. Calculation

    定义一个Strategy接口,其中定义一个方法,用于计算 using System; using System.Collections.Generic; using System.Linq; usin ...

  3. MyEclipse启动失败

    日志的一部分: !SESSION 2014-09-24 11:47:03.156 -----------------------------------------------eclipse.buil ...

  4. 获取CPUID等

    unit CommonUnit; interface uses Windows, SysUtils, DateUtils; Const CPUVendorIDs: .. ] of string = ( ...

  5. python False

    None 空字符串 空列表 空元组 空字典 false为False

  6. Delphi Xe2 后的版本如何让Delphi程序启动自动“以管理员身份运行"

    由于Vista以后win中加入的UAC安全机制,采用Delphi开发的程序如果不右键点击“以管理员身份运行”,则会报错. 在XE2以上的Delphi版本处理这个问题已经非常简单了. 右建点击工程,选择 ...

  7. PHP memcached 扩展的安装

    PHP memcached 扩展的安装 1.下载相关的源码包(软件版本自己选择) memcached-1.4.15 , http://memcached.org/ //Memcached服务端. me ...

  8. Javascript Window Location

    window.location 对象在编写时可不使用 window 这个前缀. URL : 统一资源定位符 (Uniform Resource Locator) 说明: 完整的URL示例:scheme ...

  9. 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法

    前言相信这样一个问题,大家都不会陌生,“有什么的方法可以使Android的程序APK不用安装,而能够直接启动”.发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实现这个 ...

  10. 22、JSON/jQuery上

      1)掌握JSON及其应用 2)了解jQuery的背景和特点 3)理解js对象和jQuery对象的区别 4)掌握jQuery九类选择器及应用(上)   声明:今天服务端我们使用Struts2技术 一 ...