Вы должны никогдаremove
из List
при переборе , Что вы делаете.
Рассмотрите тривиальный пример, у меня есть список {1,2,3,4,5}
. Допустим, его 0-проиндексированы, и я хочу, чтобы удалить все числа больше 3.
0 - элемент списка 1
, держать
1 - Список элемент 2
, держать
2 - Список элемент 3
, удалить , Все элементы сдвинуты, список теперь {1,2,4,5}
.
3 - Список элемент 5
, удалить
4 - элемент списка не упс, там больше нет 4
Так что я проскочил конец List
, потому что я взял размер, чтобы быть 5
, когда я начал итерацию, но это стало 4
после того, как я удалил элемент по индексу 2
, и он стал 3
, когда я удалил элемент по индексу 3
.
Вы можете сказать: "Ах-ха, я могу это исправить с while
цикла":
int i = 1;
while(i < teams.size()) {
//do stuff
}
Но это еще хуже:
0 - элемент списка 1
, держать
1 - Элемент списка 2
, keep
2 - Элемент списка 3
, удалить. Все элементы сдвинуты, список теперь {1,2,4,5}
.
3 - Элемент списка 5
, remove
Таким образом, никаких ошибок. Похоже, проблема исправлена. Но что содержит список? Он содержит {1,2,4}
. Но 4
больше 3
. Он был пропущен из-за сдвига индекса. У вас теперь еще более коварная ошибка.
Если вы используете правильный усиленную цикл Еогеасп как так:
for(final String team : teams) {
//do stuff with team
}
вы бы, правильно, получил ConcurrentModificationException
.Это всего лишь одна из многих причин использовать расширенный цикл foreach, а не цикл по индексу.
Для того, чтобы сделать то, что вы хотите использовать Iterator
:
final Iterator<String> iter = teams.iterator();
while(iter.hasNext()) {
if(iter.next().equals(testString))
iter.remove();
}
Я повторю свой комментарий:
Пожалуйста всегда использование Java naming conventions. Переменные всегда должны быть в camelCase
. PascalCase
зарезервирован для занятий.
UPDATE
Это может быть проще, так что используйте метод indexOf
, чтобы найти имя команды в List
и удалить необходимые элементы
public void remove(final List<String> teams, final String name) {
final int idx = teams.indexOf(name);
if(idx < 0)
throw new IllegalArgumentException("Team " + name + " not present in list.");
for(int i = idx + 2; i >= idx; --i)
teams.remove(i);
}
Это очень важно, чтобы удалить элементы в обратном порядке. Это связано с той же проблемой, что и выше, если вы удаляете элемент по индексу (например) 10
, тогда предмет, который был в индексе 11
, перемещается вниз. Поэтому, когда вы идете, чтобы удалить элемент по индексу 11
, вы фактически удаляете элемент, изначально это был индекс 12
.
Вы можете использовать подвох
for(int i = 0; i < 2; ++i)
teams.remove(idx)
Т.е. продолжайте удалять элемент по найденному индексу, так как список будет перемешаться вниз, чтобы заполнить пробел, вы фактически удалите необходимый элемент и два, которые были над ним. Я думаю, что это делает код очень трудным для чтения. Вероятно, вы забудете этот трюк, а затем вернетесь к коду и должны решить, что он делает.
Пожалуйста ** всегда ** использовать Java именования. Переменные должны ** всегда ** находиться в 'camelCase'. 'PascalCase' зарезервирован для классов. Этот код неразборчив, я должен сконцентрироваться, чтобы даже разобраться в том, что такое 'class' и что такое переменная. Правильно отредактируйте свой код. И отформатируйте его. –