Map中根据条件删除元素
今天在写程序过程中,需要根据判断条件删除一个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)函数来添加元素,也会出现同样的问题,所以同样需要使用迭代器的相应函数来添加。
Map中根据条件删除元素的更多相关文章
- 【Matlab开发】matlab删除数组中符合条件的元素与散点图绘制
[Matlab开发]matlab删除数组中符合条件的元素与散点图绘制 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ matlab删除数组中符合条件的元素 如 ...
- JavaScript向select下拉框中加入和删除元素
JavaScript向select下拉框中加入和删除元素 1.说明 a 利用append()方法向下拉框中加入元素 b 利用remove()方法移除下拉框中最后一个元素 2.设计源代码 < ...
- JavaScript向select下拉框中添加和删除元素
JavaScript向select下拉框中添加和删除元素 1.说明 a 利用append()方法向下拉框中添加元素 b 利用remove()方法移除下拉框中最后一个元素 2.设计源码 < ...
- Lambda 表达式遍历集合时用remove方法删除list集合中满足条件的元素问题
一:循环遍历list集合的四种方式 简单for循环 iterator循环 增加for循环 Lanbda表达式 二:四种遍历方式的用法示例 //简单for循环 List<SalaryAdjustm ...
- STL 中 使用迭代器删除元素的问题
在vector中删除,大家都知道,直接erase的话,这种写法很有问题.因为erase(iter)之后iter指针就变成野指针了,此时继续iter++就会出问题. for(auto iter = v. ...
- Java中ArrayList的删除元素总结
Java中循环遍历元素,一般有for循环遍历,foreach循环遍历,iterator遍历. 先定义一个List对象 List<String> list = new ArrayList&l ...
- 从LIst集合中安全的删除元素
package cn.rocker.list; import java.util.ArrayList; import java.util.Iterator; import java.util.List ...
- go语言学习--map中键值得删除
测试 map1 中是否存在 key1: 在例子 8.1 中,我们已经见过可以使用 val1 = map1[key1] 的方法获取 key1 对应的值 val1.如果 map 中不存在 key1,val ...
- 判定map中是否存在某元素
判断某key是否存在可以使用map的count方法来间接判定 count接受一个参数key值,返回map中key值为给定值的元素总数 map<int, string> i_to_s_map ...
随机推荐
- Mac Python PyQt5 环境搭建
pip install pyqt5 测试开发环境 在Terminal里敲下以下代码,如果没有报错就说明安装成功了. python -c "import PyQt5" 或是如下图,导 ...
- LFU Cache
2018-11-06 20:06:04 LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”. ...
- MySQL Server and Server-Startup Programs
1. mysqld-The MySQL Server mysqld,also known as mysql server, is the main program that does most of ...
- Python 编程快速上手 第五章总结
第五章 字典和结构化数据 创建数组 格式:myCat = {'size':'fat','color':'gray',disposition':'loud'} 对字典的操作 通过[ ] 访问字典的值 [ ...
- 尝试重新(多次反复)处理某个逻辑的示例(good)
以下例程的优点: 1.可以重新尝试某个动作 2.另外,在重新尝试的同时,可以做一些逻辑判断及标记的初始化 public static bool RetryLogin() { ...
- LeetCode--232--用栈实现队列
问题描述: 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队 ...
- ActiveSupport::Concern 和 gem 'name_of_person'(300✨) 的内部运行机制分析
理解ActiveRecord::Concern: 参考:include和extend的区别: https://www.cnblogs.com/chentianwei/p/9408963.html 传统 ...
- 最新的vueWebpack项目
最近优化了我的vueWebpack多入口框架,感觉清新了好多:http://pan.baidu.com/s/1bNYJp0
- SWUST OJ(953)
单链表的删除操作的实现 #include <stdio.h> #include <stdlib.h> typedef struct LinkNode //单链表节点结构的定义 ...
- MyBatis动态sql之${}和#{}区别
前言 接触mybatis也是在今年步入社会之后,想想也半年多了,缺没时间去系统的学习,只知道大概,也是惭愧. 不知道有多少刚毕业的同学和我一样,到现在还没仔仔细细去了解你每天都会见到使用到的框 ...