Reputation: 40721
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
Reputation: 310883
Use the Iterator of the entry set, the key set, or the value set, and call Iterator.remove()
.
Upvotes: 5
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:
keySet()
. Or better still, don't Use Hashtable
.Upvotes: 3
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
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