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 ...
随机推荐
- C# ---- GC中代的递增规律
只有当对象所在代被 Collect 了,改对象所在代才会加 1 ,代值最大为 2 示例1: using System; namespace myMethod { class People{} clas ...
- 安装adt插件后工具栏不显示android相关图标
一:问题 安装好ADT后,工具栏不显示android相关的图标: 二:解决办法 这是ec设置问题,解决办法: Eclipse ->window->Perpective->custom ...
- Can't find kernel text map area from kcore
kernel : 4.9.51kexec-tools : 2.0.4 1.~ # ./kexec -p /boot/vmlinuz --initrd=/boot/initrd --command-li ...
- 架构探险笔记5-使框架具备AOP特性(下)
开发AOP框架 借鉴SpringAOP的风格,写一个基于切面注解的AOP框架.在进行下面的步骤之前,确保已经掌了动态代理技术. 定义切面注解 /** * 切面注解 */ @Target(Element ...
- php字符串 统计个数
方法一 $arr=str_split($str); $arr=array_count_values($arr); /* * 方法二 * */ $arr = str_split($str); $a2 = ...
- python3 设置滚动条
#!python3#coding=utf-8from selenium import webdriverfrom selenium.webdriver.common.by import Byimpor ...
- CentOS6.8逻辑卷管理实战
CentOS6.8逻辑卷管理实战 要求:利用现有的四块磁盘,创建一个有两个PV组成的大小为80G的名为testvg的VG:要求PE大小为16MB, 而后在卷组中创建大小为5G的逻辑卷testlv:挂载 ...
- Java编码 蛇形矩阵的构建与遍历输出
一.蛇形矩阵的构建,并按行输出 例: 输入:n, 生成n*n的蛇形矩阵 1 2 3 8 9 4 7 6 5 输出:1 2 3 8 9 4 7 6 5 java编码 public static void ...
- 使用telnet模拟邮件的收发
smtp协议是一个简单的邮件传输协议,利用它我们可以将邮件发送给别人,这里将通过telnet这个程序利用smtp协议从网易向gmail发送一封邮件 基本步骤如下: 1.使用telnet连接smtp服务 ...
- Oracle中序列(Sequence)详解
一 序列定义 序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字).不占用磁盘空间,占用内存. 其主要用途是生成表的主键值,可以在插入语句中引用,也 ...