C
Charles Morison
An explanation of why this happens would be great. To wit:
Given a collection defined as follows:
private java.util.List<TableEntryStatusNode> tableEntryStatusNodes;
And constructed as follows (it is used in a multi-threaded environment):
tableEntryStatusNodes = Collections.synchronizedList (new
LinkedList<TableEntryStatusNode> ());
I used to be able to scan the collection to remove elements from the
collection using the iterator approach as follows with out any problems:
for (Iterator<TableEntryStatusNode> iterator =
tableEntryStatusNodes.listIterator (); iterator.hasNext (); )
{
if (iterator.next ().getBasicType () ==
TableEntryStatusNode.BASIC_TYPE_NOT_USED)
{
iterator.remove ();
}
}
I attempted to change the code to the new "for each" approach provided
in 1.5 as follows:
for (TableEntryStatusNode node : tableEntryStatusNodes)
{
if (node.getBasicType () == TableEntryStatusNode.BASIC_TYPE_NOT_USED)
{
tableEntryStatusNodes.remove (node);
}
}
This resulted in a run-time error with the tail end of the stack trace
stating:
Exception in thread "AWT-EventQueue-0"
java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
at java.util.LinkedList$ListItr.next(Unknown Source)
This left me with the need for two for loops in order to do what one for
loop did before if I wanted to use the new "for each" approach:
java.util.List<TableEntryStatusNode> nodesToRemove = new
LinkedList<TableEntryStatusNode> ();
for (TableEntryStatusNode node : tableEntryStatusNodes)
{
if (node.getBasicType () == TableEntryStatusNode.BASIC_TYPE_NOT_USED)
{
nodesToRemove.add (node);
}
}
if (!nodesToRemove.isEmpty ())
{
for (TableEntryStatusNode node : nodesToRemove)
{
tableEntryStatusNodes.remove (node);
}
}
So it would seem that the "for each" construct is not a completely
transparent replacement for using iterators.
Is this mentioned by Sun or is this an error in their implementation?
Or is it an error in my implementation?
Thanks for any help in advance.
Given a collection defined as follows:
private java.util.List<TableEntryStatusNode> tableEntryStatusNodes;
And constructed as follows (it is used in a multi-threaded environment):
tableEntryStatusNodes = Collections.synchronizedList (new
LinkedList<TableEntryStatusNode> ());
I used to be able to scan the collection to remove elements from the
collection using the iterator approach as follows with out any problems:
for (Iterator<TableEntryStatusNode> iterator =
tableEntryStatusNodes.listIterator (); iterator.hasNext (); )
{
if (iterator.next ().getBasicType () ==
TableEntryStatusNode.BASIC_TYPE_NOT_USED)
{
iterator.remove ();
}
}
I attempted to change the code to the new "for each" approach provided
in 1.5 as follows:
for (TableEntryStatusNode node : tableEntryStatusNodes)
{
if (node.getBasicType () == TableEntryStatusNode.BASIC_TYPE_NOT_USED)
{
tableEntryStatusNodes.remove (node);
}
}
This resulted in a run-time error with the tail end of the stack trace
stating:
Exception in thread "AWT-EventQueue-0"
java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
at java.util.LinkedList$ListItr.next(Unknown Source)
This left me with the need for two for loops in order to do what one for
loop did before if I wanted to use the new "for each" approach:
java.util.List<TableEntryStatusNode> nodesToRemove = new
LinkedList<TableEntryStatusNode> ();
for (TableEntryStatusNode node : tableEntryStatusNodes)
{
if (node.getBasicType () == TableEntryStatusNode.BASIC_TYPE_NOT_USED)
{
nodesToRemove.add (node);
}
}
if (!nodesToRemove.isEmpty ())
{
for (TableEntryStatusNode node : nodesToRemove)
{
tableEntryStatusNodes.remove (node);
}
}
So it would seem that the "for each" construct is not a completely
transparent replacement for using iterators.
Is this mentioned by Sun or is this an error in their implementation?
Or is it an error in my implementation?
Thanks for any help in advance.