title: Why doesn't this code throw a ConcurrentModificationException?
body: <p>Why doesn't this code throw a <code>ConcurrentModificationException</code>? It modifies a <code>Collection</code> while iterating through it, without using the <code>Iterator.remove()</code> method, which is meant to be <a href="https://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re">the only safe way of removing</a>.</p>
  
  <pre><code>List&lt;String&gt; strings = new ArrayList&lt;&gt;(Arrays.asList("A", "B", "C"));
  for (String string : strings)
      if ("B".equals(string))
          strings.remove("B");
  System.out.println(strings);
  </code></pre>
  
  <p>I get the same result if I replace the <code>ArrayList</code> with a <code>LinkedList</code>. However if I change the list to <code>("A", "B", "C", "D)</code> or just <code>("A", "B")</code> I get the exception as expected. What is going on? I am using <code>jdk1.8.0_25</code> if that is relevant.</p>
  
  <p><strong>EDIT</strong> </p>
  
  <p>I've found the following link</p>
  
  <p><a href="http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078" rel="nofollow noreferrer">http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078</a></p>
  
  <p>The relevant section is</p>
  
  <blockquote>
    <p>The naive solution is to add comodification checks to hasNext in AbstractList, but this doubles the cost of comodification checking. 
    It turns out that it is sufficient to do the test only on the last
    iteration, which adds virtually nothing to the cost.  In other words,
    the current implementation of hasNext:</p>
  
  <pre><code>    public boolean hasNext() {
          return nextIndex() &lt; size;
      }
  </code></pre>
    
    <p>Is replaced by this implementation:</p>
  
  <pre><code>    public boolean hasNext() {
          if (cursor != size())
              return true;
          checkForComodification();
          return false;
      }
  </code></pre>
    
    <p>This change will not be made because a Sun-internal regulatory body rejected it.  The formal ruling indicated that the change "has
    demonstrated the potential to have significant compatibility impact
    upon existing code."  (The "compatibility impact" is that the fix has
    the potential to replace silent misbehavior with a
    ConcurrentModificationException.)</p>
  </blockquote>