Search code examples
javacollectionssynchronizationsetcopy-on-write

got UnsupportedOperationException while modifying CopyOnWriteArraySet


Studying Java Generics and Collection book by By Maurice Naftalin, Philip Wadler, I left off at CopyOnWriteArraySet section, trying practice while studying to make it stick to my mind, But I faced a problem, let me reveal my trivial code :

  CopyOnWriteArrayList<Character> modifiableSet = new CopyOnWriteArrayList<Character>(); 
   modifiableSet.add('a');modifiableSet.add('d');
    for(Character ch:modifiableSet){  
        if(ch.equals('d')){
        modifiableSet.remove(ch); // compiler neglects this, as expected,
                                              // since CopyOnWriteArraySet is synchronous
        }               
    }

   for(Iterator<Character> its = modifiableSet.iterator();its.hasNext();){ 
   Character firstElement = its.next();
   if(firstElement.equals('a'))its.remove();// compiler does not give a damn here              
    // since CopyOnWriteArrayList is synchronous java.lang.UnsupportedOperationException 
    // surprisingly,  wondering If CopyOnWriteArrayList is synchronous,
// why the compiler shouts here ?                         
 }

What I my brain understood so far, that whenever modification happens to CopyOnWriteArraySet, a new backing array created with the new changes, the question is, Does going through CopyOnWriteArraySet through iterator() takes place on backing array or front array, If It's convenient to say front array, It sounds reasonable to me CopyOnWriteArraySet.remove() works on front array, and CopyOnWriteArraySet.iterator().remove() works on backing array, Am I right ?

any flash put into this far appreciated, thank you all .


Solution

  • CopyOnWriteArraySet API is quite clear about it

    •Iterators do not support the mutative remove operation. 
    

    This is because CopyOnWriteArraySet's Iterators "rely on unchanging snapshots of the array at the time the iterators were constructed".