以下代码是否可以安全地删除Hashtable中的元素?
Enumeration keys = siCache.keys(); //siCache is Hashtable
while(keys.hasMoreElements())
{
String k = (String) keys.nextElement();
Object v = siCache.get(k);
if(condition) siCache.remove(k);
}
答案 0 :(得分:5)
使用条目集,密钥集或值集的迭代器,并调用Iterator.remove()
。
答案 1 :(得分:2)
枚举密钥时从Hashtable
删除元素可能存在风险。以下是javadoc所说的内容:
“因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险.Hashtable的键和元素方法返回的枚举是不是快速失败。“
含义很明确:如果你这样做,任意的非确定性行为都是可能的。
解决方案:
keySet()
。或者更好的是,不要使用Hashtable
。答案 2 :(得分:1)
使用...
之间存在明显差异Enumeration keys = siCache.keys();
并使用......
Iterator iterator = siCache.entrySet().iterator()
在迭代时删除集合中的元素时,选项1不会抛出ConcurrentModificationException,而选项2将会抛出。
至于为什么......我相信当您在示例中创建密钥枚举时,它是表密钥集的文字副本,与表本身的修改不同步。
这对您来说可能是也可能不是问题。如果同时使用该表,但您可能希望切换到使用集合迭代器。
答案 3 :(得分:-1)
很安全。但是是什么让你认为它可能不是?
使用以下代码进行测试。
public static void main(String[] args) {
// TODO Auto-generated method stub
Hashtable siCache = new Hashtable();
siCache.put("key", "value");
siCache.put("key1", "value1");
Enumeration keys = siCache.keys(); //siCache is Hashtable
while(keys.hasMoreElements())
{
String k = (String) keys.nextElement();
Object v = siCache.get(k);
if(true) siCache.remove(k);
}
System.out.println(siCache.size());
}
输出:0