删除迭代中哈希表的元素

时间:2011-03-04 06:11:23

标签: java hashtable

以下代码是否可以安全地删除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);

    }

4 个答案:

答案 0 :(得分:5)

使用条目集,密钥集或值集的迭代器,并调用Iterator.remove()

答案 1 :(得分:2)

枚举密钥时从Hashtable删除元素可能存在风险。以下是javadoc所说的内容:

  

“因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险.Hashtable的键和元素方法返回的枚举是不是快速失败。“

含义很明确:如果你这样做,任意的非确定性行为都是可能的。

解决方案:

  • 如果您使用的是J2SE,请使用keySet()。或者更好的是,不要使用Hashtable
  • 如果您使用的是J2ME,请构建一个要删除的密钥列表,稍后将其删除......或者继续祷告: - )。

答案 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