Perché questo codice non genera uno ConcurrentModificationException
? Modifica uno Collection
durante l'iterazione, senza utilizzare il metodo Iterator.remove()
, che deve essere the only safe way of removing.Perché questo codice non lancia ConcurrentModificationException?
List<String> strings = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String string : strings)
if ("B".equals(string))
strings.remove("B");
System.out.println(strings);
ottengo lo stesso risultato se si sostituisce la ArrayList
con un LinkedList
. Tuttavia se cambio l'elenco in ("A", "B", "C", "D)
o solo ("A", "B")
ottengo l'eccezione come previsto. Cosa sta succedendo? Sto usando jdk1.8.0_25
se questo è rilevante.
EDIT
ho trovato il seguente link
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078
La sezione rilevante è
La soluzione ingenua è quella di aggiungere controlli comodification a hasNext in AbstractList, ma questo raddoppia il costo del controllo della comodificazione. Si scopre che è sufficiente eseguire il test solo sull'ultima iterazione , che non aggiunge praticamente nulla al costo. In altre parole, l'attuale implementazione di hasNext:
public boolean hasNext() { return nextIndex() < size; }
è sostituita da questa implementazione:
public boolean hasNext() { if (cursor != size()) return true; checkForComodification(); return false; }
Questo cambiamento non verranno effettuate a causa di un organismo di regolamentazione Sun-interno ha respinto. La decisione formale ha indicato che il cambiamento "ha dimostrato che ha un impatto significativo sulla compatibilità sul codice esistente." (Il "impatto compatibilità" è che la correzione ha il potenziale per sostituire malfunzionamento muto con un ConcurrentModificationException.)
Perché 'ConcurrentModificationException' viene gettato su un "best-effort" base –
Eventuali duplicati: [java.util.ConcurrentModificationException non torta quando previsto] (http://stackoverflow.com/questions/ 24980651/java-util-concurrentmodificationexception-not-thrown-when-expected) – Pshemo
Mi piace come il motivo per cui Sun non ha apportato il cambiamento è che potrebbe far sì che alcuni codici errati inizino a lanciare l'eccezione che avrebbe dovuto generare il possibile duplicato – Mshnik