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);
}
Use the Iterator of the entry set, the key set, or the value set, and call Iterator.remove()
.
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 UseHashtable
. - If you are using J2ME, build a list of keys to be removed, and remove them later ... or pray hard :-).
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.
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
精彩评论