Java : 方法接受一个 Map 参数,需要对这个 map 做遍历。怎样才是安全的?

2018-09-28 16:21:30 +08:00
 theworldsong

举例:

test(Map<String, String> m) {

}

现在要在 test 内遍历 m。

但是:

老铁们,有办法吗

6597 次点击
所在节点    程序员
42 条回复
af463419014
2018-09-28 16:26:18 +08:00
入参 m 的类型改成 ImmutableMap
yinzhili
2018-09-28 16:32:56 +08:00
com.google.common.collect.ImmutableMap
xuhaoyangx
2018-09-28 16:46:47 +08:00
你这问题 让我想起了 Java 形参和实参

删除操作用 Iterator 去做
z3jjlzt
2018-09-28 16:49:52 +08:00
final 修饰入参
johnj
2018-09-28 17:34:15 +08:00
Collections.unmodifiableMap() 包一下
johnj
2018-09-28 17:35:33 +08:00
我说的不对
hand515
2018-09-28 18:04:19 +08:00
@z3jjlzt #4 这个不对,参数的 final 搞错了
linlinismine
2018-09-28 18:28:57 +08:00
copy 一份
psuwgipgf
2018-09-28 18:37:52 +08:00
不明白怎么解决,关注一下。
aa6563679
2018-09-28 18:43:28 +08:00
@linlinismine 可能 copy 中被改了
crayygy
2018-09-28 18:45:05 +08:00
8l 的方法是可以的,在传入之前先从原 collection 中复制一份,然后再传入复制出来的对象
elgae
2018-09-28 18:55:59 +08:00
加个锁,遍历时独占
sagaxu
2018-09-28 19:22:10 +08:00
Map 只是个接口,你需要一个支持并发读写的实现
talen666
2018-09-28 19:36:28 +08:00
把声明 Map 的地方改成线程安全的 Map
psuwgipgf
2018-09-28 20:43:40 +08:00
@talen666 方法可以,不过他说的业务复杂用的地方也多,这样会影响整个系统的速度吧??
oaix
2018-09-28 20:54:40 +08:00
重试
boywang004
2018-09-28 21:45:42 +08:00
只要调用 iterator()都会有机会上抛 ConcurrentModifyException,先做保护性拷贝,拷贝期间肯定会调用 iterator(),只要捕获 CME 重新拷贝,直到某次拷贝时没有改动成功拷出来为止……

上面说的加锁包 unmodifiableMap 啥的……=__=b
micean
2018-09-28 22:38:38 +08:00
只能在 test 里面操作的话根本做不到
ysweics
2018-09-28 22:45:56 +08:00
明确一下问题,具体的需求是怎么样,比如这个 map 开始传递过来的时候只有 10 个 kv ,然后你在便利的时候,remove 两个 kv,你需要的结果是开始的 10 个 kv,还是剩余的 8 个 kv
zzorzz
2018-09-28 23:24:51 +08:00
只是在 test 遍历,没有新启动一个新线程进行遍历的话,应该无须考虑同步问题,谁调用谁负责(方法调用者在自己的线程去考虑和别的线程同步)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/493552

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX