У меня также была проблема с OSX. Решение было раскомментировано extension = pgsql.so
в php.ini.default
и удалением суффикса .default
, так как файла php.ini
не было.
Если вы используете XAMPP, файл php.ini находится в / XAMPP / xampfiles / etc
Поскольку отказоустойчивое поведение итератора не гарантируется.
Вы получаете это исключение, потому что вы
Плохо:
// we're using iterator
for (Iterator<String> i = c.iterator(); i.hasNext();) {
// here, the collection will check it hasn't been modified (in effort to fail fast)
String s = i.next();
if(s.equals("lalala")) {
// s is removed from the collection and the collection will take note it was modified
c.remove(s);
}
}
Хорошо:
// we're using iterator
for (Iterator<String> i = c.iterator(); i.hasNext();) {
// here, the collection will check it hasn't been modified (in effort to fail fast)
String s = i.next();
if(s.equals("lalala")) {
// s is removed from the collection through iterator, so the iterator knows the collection changed and can resume the iteration
i.remove();
}
}
Теперь, чтобы перейти к следующему элементу, «почему»: в приведенном выше коде обратите внимание на то, как выполняется проверка модификации - удаление помещает коллекцию как измененную, а следующая итерация проверяет любые изменения и терпит неудачу, если она обнаруживает изменение коллекции. Еще одна важная вещь: ArrayList
(не уверенный в других сборниках) делает not проверкой на модификацию в hasNext()
.
Поэтому могут произойти две странные вещи:
ArrayList.hasNext()
будет также возвращать false
, потому что итератор current index
теперь указывает на последний элемент (бывший второй по-последнему). Таким образом, даже в этом случае после удаления нет «следующего» элемента Обратите внимание, что все это соответствует документации ArrayList :
Обратите внимание, что неэффективное поведение итератора не может быть гарантировано, поскольку, как правило, невозможно сделать какие-либо серьезные гарантии при наличии несинхронизированной параллельной модификации. Неуправляемые итераторы бросают ConcurrentModificationException с максимальной эффективностью. Поэтому было бы неправильно писать программу, зависящую от этого исключения, за ее правильность: неудачное поведение итераторов должно использоваться только для обнаружения ошибок.
blockquote>Отредактировано для добавления:
Этот вопрос дает некоторую информацию о том, почему проверка параллельной модификации не выполнена в
]hasNext()
и выполняется только вnext()
.
Если вы посмотрите на исходный код для итератора ArrayList
(частный вложенный класс Itr
), вы увидите недостаток в коде.
Код должен быть с ошибкой, быстрый, который делается внутри итератора внутри, вызывая checkForComodification()
, однако hasNext()
не делает этот вызов, вероятно, по соображениям производительности.
Вместо hasNext()
:
public boolean hasNext() {
return cursor != size;
}
Это означает, что когда вы находитесь в элементе second last в списке, а затем удалите элемент (любой элемент), размер уменьшается, а hasNext()
думает, что вы 're на последнем элементе (которого вы не были) и возвращает false
, пропуская итерацию последнего элемента без ошибок.
OOPS !!!!
hasNext()
и объяснил, как / почему он терпит неудачу. Я не собираюсь подробно объяснять, как работает весь класс итератора. Если вы не можете понять код, просто примите тот факт, что он работает при правильном использовании и не гарантирует сбой при неправильном использовании. Позже, когда вы лучше понимаете Java, вы можете снова взглянуть на нее.
– Andreas
25 November 2015 в 11:56
Из других ответов вы знаете, что является правильным способом удаления элемента в коллекции, когда вы выполняете итерацию коллекции. Я даю здесь объяснение основному вопросу. И ответ на ваш вопрос лежит в следующей трассировке стека
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()
никогда не выполняется, чтобы выбросить исключение
вы должны удалить из iterator
(i), а не collection
(c) напрямую;
попробуйте это:
for (Iterator<String> i = c.iterator(); i.hasNext();) {
String s = i.next();
if(s.equals("lalala")) {
i.remove(); //note here, changing c to i with no parameter.
}
}
EDIT:
Причина, по которой первая попытка вызывает исключение, а вторая - нет, просто из-за количества элементов в вашей коллекции.
, поскольку первый из них будет проходить цикл более одного раза и второй - только один раз. поэтому у него нет возможности выбросить исключение
Вы не можете удалить из списка, если вы просматриваете его с циклом «для каждого».
Вы не можете удалить элемент из коллекции, которую вы выполняете. Вы можете обойти это, явно используя Итератор и удалив там элемент. Вы можете использовать Итератор.
Если вы используете код ниже, вы не получите никакого исключения:
private static void removeLalala(Collection<String> c)
{
/*for (Iterator<String> i = c.iterator(); i.hasNext();) {
String s = i.next();
if(s.equals("lalala")) {
c.remove(s);
}
}*/
Iterator<String> it = c.iterator();
while (it.hasNext()) {
String st = it.next();
if (st.equals("lalala")) {
it.remove();
}
}
}
Iterator.hasNext()
, но Java почему-то не делает этого. – Jiri Tousek 25 November 2015 в 12:22