关于将HashMap替换原有Map的key保持value不变报错java.util.ConcurrentModificationException的处理方案

前言

由于苦逼的在公司支持上线,在等待es集群分片完成过程,实在闲的无聊,将之前本地Notion记得一些笔记扔上来一些打发下时间吧( ̄. ̄)

需求

有个类似下面的数据为 Map<String, List<Map<String,String>>>,其中key为资源id,value为List<Map<String,String>>,

{
	"4757637007194717896": [{
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "System4",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "System1",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "System4",
		"oracleTableSpaceSizeGB": "3"
	}],
	"7669745150692329757": [{
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "BuildTest4",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "BuildTest6",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "BuildTest7",
		"oracleTableSpaceSizeGB": "3"
	}]
}

还有个关于资源id和ip的映射

{
	"4757637007194717896": "192.168.189.229",
	"7669745150692329757": "192.168.180.158",
	"4647551750046525616": "192.168.180.158",
	"7316775260328274247": "192.168.120.78"
}

现在需要将第一个Map里面的资源id替换为与其映射的ip

错误的处理方法

通过foreach遍历方法处理,由于HashMap是非线程安全的,会报错,

正确的处理方法

通过将HashMap转化为对应的ConcurrentHashMap来处理,来确保避免发生这个问题,因为ConcurrentHashMap是线程安全的

写个方法实现将普通的HashMap转化为线程安全的ConcurrentHashMap

   public static ConcurrentHashMap<String,Object> transferMaptoConcurrentHashMap(Map<String, List<Map<String,String>>> map){
        ConcurrentHashMap<String,Object> map2=new ConcurrentHashMap<>();
        for (String s : map.keySet()) {
            map2.put(s, map.get(s));
        }
        return map2;
    }

最终实现替换key的样例代码如下,注意这里替换的时候value值要通过remove(s)的方式替换,否则会导致Map原有的key-value键值对仍然存在

Map<String,String> resIdAndIpMap=new HashMap<>();
resIdAndIpMap.put("4757637007194717896","192.168.189.229");
resIdAndIpMap.put("7669745150692329757","192.168.180.158");

ConcurrentHashMap<String, Object> concurrentHashMap = transferMaptoConcurrentHashMap(oracleTableSpaceMap);
        for (String s : concurrentHashMap.keySet()) {
             if(resIdAndIpMap.containsKey(s)){
                 concurrentHashMap.put(resIdAndIpMap.get(s),concurrentHashMap.remove(s));
             }
        }
        logger.info("组装的多个oracle实例ip以及对应的表空间资源数据为"+JSON.toJSONString(concurrentHashMap));
    }

 

执行上面代码,就会成功替换原有的key了,完美解决了

{
	"192.168.180.158": [{
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "BuildTest5",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "BuildTest2",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "BuildTest9",
		"oracleTableSpaceSizeGB": "3"
	}],
	"192.168.189.229": [{
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "System1",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "System0",
		"oracleTableSpaceSizeGB": "3"
	}, {
		"oracleTableSpaceSize": "30000",
		"oracleTableName": "System4",
		"oracleTableSpaceSizeGB": "3"
	}]
}

结语

该死的es集群分片快点结束吧,我要回去睡觉。。。。。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦岚如雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值