#java
#java
Вопрос:
Мне нужно выполнить проект, и я должен добавить людей в базу данных, а затем удалить их, но когда я пытаюсь удалить человека из arraylist, это работает, но когда я пытаюсь добавить больше, я получаю исключение index out of bounds?
public void removePerson(List<Person> CrecheList) {
if (CrecheList.isEmpty()) {
JOptionPane.showMessageDialog(null, "You need a Child or parent in the database", "Error", JOptionPane.INFORMATION_MESSAGE);
} else {
String pickid = JOptionPane.showInputDialog(null, "Please Enter an id");
int id = Integer.parseInt(pickid);
Iterator<Person> i = CrecheList.iterator();
while (i.hasNext()) {
Person p = i.next();
if (p.getID() == id) {
i.remove();
} else {
JOptionPane.showMessageDialog(null, "There is no such person in the database", "Child name", JOptionPane.INFORMATION_MESSAGE);
}
}
}
}
и когда я удаляю и пытаюсь добавить больше в arrylist, я получаю индекс за пределами?
Комментарии:
1. Пожалуйста, покажите нам также часть добавления.
2. Это какой-то сумасшедший отступ.
3. Итератор не гарантированно поддерживает .remove(). Он вызвал «NotImplementedException»?
4. @Paul: Я цитирую вопрос: «когда я пытаюсь удалить пользователя из arraylist, это работает» . Верно, заголовок вопроса довольно плохой и противоречивый.
5. @BalusC: Извините за комментарий. Я удалил его.
Ответ №1:
Полностью альтернативным подходом было бы реализовать equals()
метод в вашем Person
классе, чтобы он возвращал значение true, если ID
поля равны:
public class Person {
int id;
// Other fields/methods
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person)o;
if (this.id == p.getID()) return true;
}
return false;
}
}
Если вы это реализуете, вам не нужно перебирать элементы — вы можете просто вызвать CrecheList.remove(p);
.
Ответ №2:
Вместо этого передайте CopyOnWriteArrayList в вашу функцию удаления, которая допускает одновременные изменения, а затем:
for ( Person p : CrecheList ) {
if ( p.getID() == id ) {
CrecheList.remove(p);
}
}
Комментарии:
1. Чего мне не хватало, мне нужно было обновить массив, иначе он не знал, что он был удален.
Ответ №3:
(Это не ответ.)
Это может показаться немного излишним, но я бы полностью разбил этот код на небольшие функциональные части, чтобы помочь в тестировании.
public void removePerson(List<Person> CrecheList) {
if (CrecheList.isEmpty()) {
emptyListError();
return;
}
int id = getId();
if (!removePersonById(id)) {
couldNotRemoveError();
}
}
public boolean removePersonById(int id) {
Iterator<Person> i = CrecheList.iterator();
while (i.hasNext()) {
Person p = i.next();
if (p.getID() == id) {
i.remove();
return true;
}
}
return false;
}
// Swing-specific stuff.
public void emptyListError() {
JOptionPane.showMessageDialog(null, "You need a Child or parent in the database", "Error", JOptionPane.INFORMATION_MESSAGE);
}
public int getId() {
String pickid = JOptionPane.showInputDialog(null, "Please Enter an id");
return Integer.parseInt(pickid);
}
public void couldNotRemoveError() {
JOptionPane.showMessageDialog(null, "There is no such person in the database", "Child name", JOptionPane.INFORMATION_MESSAGE);
}
Это позволяет вам тестировать каждый функциональный компонент отдельно и предоставляет простой механизм, позволяющий различными способами удалять пользователей (например, мне всегда нравится иметь интерфейс CLI для большинства вещей, которые я делаю).
Ответ №4:
Попробуйте удалить пользователя вне повторяющегося цикла:
Person p = null;
while (i.hasNext()) {
p = i.next();
if (p.getID() == id) {
break;
}
p = null;
}
id ( p != null ) {
CrecheList.remove( p );
}
else {
JOptionPane.showMessageDialog(null, "There is no such person in the database", "Child name", JOptionPane.INFORMATION_MESSAGE);
}
Комментарии:
1. Если итератор поддерживает .remove, то удаление в цикле итератора совершенно законно и работает нормально.
2. @Paul согласился, но у него проблемы с его кодом, так что это предложение обойти, мы не знаем реализацию списка и его итератора.
3. Если он не переопределил итератор, чтобы сделать что-то глупое, он должен либо правильно поддерживать .remove, либо он должен выдать исключение.