From a TreeSet
(a SortedSet
) in Java 8:
- I call the
::headSet
method to get aSortedSet
of the objects at the front of the sorted collection. - I call
::removeAll
to delete those frontmost objects.
BAM, throws aConcurrentModificationException
.
Yet if I make another SortedSet from the headSet and pass that derived set to the ::removeAll
, no problem.
Why?
Demo code using Java 8 Update 45. Enable the line //sortedSet.removeAll( headSet );
to see the exception thrown.
String cockatiel = "Cockatiel";
SortedSet sortedSet = new TreeSet< String >( );
sortedSet.add( "Dog" );
sortedSet.add( "Cat" );
sortedSet.add( "Bird" );
sortedSet.add( "Elephant" );
sortedSet.add( cockatiel ); // Passing var rather than literal.
sortedSet.add( "Guppy" );
System.out.println( "Before: " + sortedSet );
// Direct way. FAIL
SortedSet< String > headSet = sortedSet.headSet( cockatiel );
System.out.println( "headSet: " + headSet );
//sortedSet.removeAll( headSet ); // Fails. Throws java.util.ConcurrentModificationException.
// Derived way. PASS
SortedSet<String> headSetDerived = new TreeSet<String>( headSet); // Make a TreeSet from a TreeSet.
sortedSet.removeAll( headSetDerived ); // Succeeds. Why?
System.out.println( "After: " + sortedSet );