pierrotlefou
pierrotlefou

Reputation: 40721

remove element of an hashtable in the iteration

Is following code the safe way to remove a element in the 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);

    }

Upvotes: 2

Views: 7477

Answers (4)

user207421
user207421

Reputation: 310883

Use the Iterator of the entry set, the key set, or the value set, and call Iterator.remove().

Upvotes: 5

Stephen C
Stephen C

Reputation: 718788

Removing an element from a Hashtable while enumerating the keys is potentially risky. Here's what the javadoc says:

"Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. The Enumerations returned by Hashtable's keys and elements methods are not fail-fast."

The implication is clear: arbitrary, non-deterministic behaviour is possible if you do that.

Solutions:

  • If you are using J2SE, use keySet(). Or better still, don't Use Hashtable.
  • If you are using J2ME, build a list of keys to be removed, and remove them later ... or pray hard :-).

Upvotes: 3

mmccomb
mmccomb

Reputation: 13807

There's a distinct difference between using...

Enumeration keys = siCache.keys();

and using...

Iterator iterator = siCache.entrySet().iterator()

Option 1 will not throw a ConcurrentModificationException when you remove elements in the collection whilst iterating, whereas option 2 will.

As for why... I believe that when you create the keys Enumeration in your example it's a literal copy of the tables key set, which is not kept in sync with modifications to the table itself.

This may or may not be an issue for you. If the table is used concurrently though you may want to switch to using the collections iterators.

Upvotes: 1

GuruKulki
GuruKulki

Reputation: 26418

It is safe. But what made you think it may not??

tested with the following code.

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());
    }

output : 0

Upvotes: -1

Related Questions