Java выдает IndexOutOfBounds при редактировании observableList - PullRequest
1 голос
/ 13 мая 2019

Мой учитель учил меня, что когда я обновляю объект в моем Наблюдаемом Списке, он автоматически обнаруживает изменения и уведомляет наблюдателя.Однако, когда я пытаюсь обновить человека в списке, он выбрасывает исключение индекса за пределами границ.Я не могу понять, что происходит не так.

private ObservableList<ClubPersoon> personen;

public void updatePersoon(ClubPersoon editPerson) {
        GenericDaoJpa.openPersistency();
        GenericDaoJpa.em.getTransaction().begin();
        UpdatePersoonValues(editPerson);
        GenericDaoJpa.em.getTransaction().commit();
        GenericDaoJpa.closePersistency();
}

private void UpdatePersoonValues(ClubPersoon currentLid) {
        int index = personen.indexOf(personen.stream().filter(p -> p.getId() == currentLid.getId()).findFirst());
        personen.get(index).setVoornaam(currentLid.getVoornaam());
        personen.get(index).setAchternaam(currentLid.getAchternaam());
        personen.get(index).setEmail(currentLid.getEmail());
        personen.get(index).setEmailOuders(currentLid.getEmailOuders());
        personen.get(index).setEmail(currentLid.getEmail());
        personen.get(index).setTelefoonNummer(currentLid.getTelefoonNummer());
        personen.get(index).setGeboorteDatum(currentLid.getGeboorteDatum());
        personen.get(index).setBackupTelefoon(currentLid.getBackupTelefoon());
        personen.get(index).setScore(currentLid.getScore());
        personen.get(index).setGeslacht(currentLid.getGeslacht());
        personen.get(index).setRijksregisternummer(currentLid.getRijksregisternummer());
        personen.get(index).setRol(currentLid.getRol());
        personen.get(index).setGraad(currentLid.getGraad());
        personen.get(index).setLocatie(currentLid.getLocatie());
        personen.get(index).setVerwachteDagen(currentLid.getVerwachteDagen());
        personen.get(index).setActiviteiten(currentLid.getActiviteiten());
    }

Это путь ошибки:

Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
    at java.base/java.util.Vector.elementData(Vector.java:761)
    at java.base/java.util.Vector.get(Vector.java:782)
    at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at domein.Club.UpdatePersoonValues(Club.java:143)
    at domein.Club.updatePersoon(Club.java:80)
    at domein.DomeinController.updatePersoon(DomeinController.java:113)
    at gui.PersoonDetailController.handleBtnOpslaan(PersoonDetailController.java:186)

1 Ответ

3 голосов
/ 13 мая 2019

Как указано в документации List.indexOf(Object), этот метод возвращает -1, если List не содержит объект, переданный в качестве аргумента.Попытка получить доступ к List через индекс -1 всегда вызовет IndexOutOfBoundsException (или ArrayIndexOutOfBoundsException, так как вы, кажется, оборачиваете Vector).

Тем не менее, путьВы в настоящее время реализовали свой метод, всегда приведет к возврату -1.Обратите внимание на подпись indexOf;он принимает Object, а не E.Это означает, что вы можете передать любой объект в этот метод и ваш код скомпилируется.Теперь взгляните на тип возврата Stream.findFirst() - он возвращает Optional<T>.Другими словами, ваш код эквивалентен:

Optional<ClubPerson> optional = personen.stream().filter(p -> p.getId() == currentLid.getId()).findFirst();
int index = personen.indexOf(optional);
...

Поскольку personen является ObservableList<ClubPerson>, он не может содержать Optional<ClubPerson> элементов.

Это не совсем яснопочему вы пытаетесь найти ClubPerson в списке, а затем запрашиваете индекс этого элемента, только чтобы просто снова получить доступ к списку с указанным индексом, чтобы изменить ClubPerson, который вы уже нашли.Почему бы просто не изменить ClubPerson напрямую?Вы даже можете использовать Optional.ifPresent(Consumer).

personen.stream().filter(p -> p.getId() == currentLid.getId()).findFirst().ifPresent(p -> {
    p.setVoornaam(currentLid.getVoornaam());
    p.setAchternaam(currentLid.getAchternaam());
    p.setEmail(currentLid.getEmail());
    p.setEmailOuders(currentLid.getEmailOuders());
    p.setEmail(currentLid.getEmail());
    p.setTelefoonNummer(currentLid.getTelefoonNummer());
    p.setGeboorteDatum(currentLid.getGeboorteDatum());
    p.setBackupTelefoon(currentLid.getBackupTelefoon());
    p.setScore(currentLid.getScore());
    p.setGeslacht(currentLid.getGeslacht());
    p.setRijksregisternummer(currentLid.getRijksregisternummer());
    p.setRol(currentLid.getRol());
    p.setGraad(currentLid.getGraad());
    p.setLocatie(currentLid.getLocatie());
    p.setVerwachteDagen(currentLid.getVerwachteDagen());
    p.setActiviteiten(currentLid.getActiviteiten());
});

Если элемент, отсутствующий в списке, является ошибкой, вы можете вместо этого использовать что-то вроде Optional.orElseThrow(Supplier) или Optional.orElseThrow() (Java 10+).

ClubPerson p = personen.stream().filter(p -> p.getId() == currentLid.getId())
        .findFirst()
        .orElseThrow(); // throws NoSuchElementException if element not found
// set properties of "p"...
...