Из других ответов вы знаете, что является правильным способом удаления элемента в коллекции, когда вы выполняете итерацию коллекции. Я даю здесь объяснение основному вопросу. И ответ на ваш вопрос лежит в следующей трассировке стека
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.ii4sm.controller.Evil.removeLalala(Evil.java:23)
at com.ii4sm.controller.Evil.main(Evil.java:17)
В stacktrace очевидно, что строка i.next();
выдает ошибку. Но когда у вас есть только два элемента в коллекции.
Collection<String> c = new ArrayList<String>();
c.add("lalala");
c.add("lalala");
removeLalala(c);
System.err.println(c);
Когда первый удаляется i.hasNext()
возвращает false, а i.next()
никогда не выполняется, чтобы выбросить исключение
Попробовав простую программу (используя как 0, так и 100, чтобы показать разницу между «специальными» константами и общими), компилятор Sun Java 6 выдаст тот же байт-код для 1 и 2 (случаи 3 и 4 идентичны [2]
Так, например:
double x = 100;
double y = 100.0;
компилируется в:
0: ldc2_w #2; //double 100.0d
3: dstore_1
4: ldc2_w #2; //double 100.0d
7: dstore_3
Однако я могу " t увидеть что-либо в Спецификации языка Java , гарантируя это расширение времени с постоянным выражением. Время компиляции сужается для таких случаев, как:
byte b = 100;
, как указано в разделе 5.2 , но это не совсем то же самое.
Возможно, кто-то с более острыми глазами, чем я, может найти там какую-то гарант ...
для Java Я точно не знаю, в C это может быть действительно опасно, если вы опустите этот D в конце, так как он не изменит верхние байты, что может повлиять на то, что в вашей переменной лежит число, которое вы на самом деле не ставили в!
В Java у меня была действительно большая проблема с instatntiating BigDecimal - новый BigDecimal (0) и новый bigDecimal (0L) - это не то же самое, вы можете почувствовать это, если вы перенести свой код с Java 1.4 на Java 1,5. Не знаю, почему они были небрежны в этом, может быть, они должны были это сделать.
Для первого:
double dummy = 0;
целочисленный литерал 0
преобразуется в двойное с расширением примитивного преобразования, см. 5.1.2 Расширение примитивного преобразования в Спецификация языка Java. Обратите внимание, что это делается исключительно компилятором, это не влияет на созданный байт-код.
Для других:
double dummy = 0.0;
double dummy = 0.0d;
double dummy = 0.0D;
Эти три точно такие же - 0.0
, 0.0d
и 0.0D
- всего три разных способа записи литерала double
. См. 3.10.2 Литералы с плавающей запятой в JLS.
Последние 3 должны быть одинаковыми. Литерал с правой стороны уже двойной. «D» или «D» является неявным, когда у вас есть десятичный литерал.
Первый из них несколько отличается тем, что 0 - это int-литерал, который будет расширен до двойника. Я не знаю, создает ли в этом случае другой байт-код или нет; результат все равно должен быть идентичным.