Java在编辑observableList时抛出IndexOutOfBounds

时间:2019-05-13 15:05:58

标签: java indexoutofboundsexception observablelist

我的老师告诉我,当我更新“可观察列表”中的对象时,它会自动检测到更改并通知观察者。但是,当我尝试更新列表中的人员时,它会抛出索引超出范围的异常。我不知道出了什么问题。

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 个答案:

答案 0 :(得分:3)

List.indexOf(Object)的文档所述,如果-1不包含作为参数传递的对象,则该方法返回List。尝试通过索引List访问-1总是会导致IndexOutOfBoundsException(或ArrayIndexOutOfBoundsException,因为您似乎要包装Vector)。 / p>

也就是说,您当前实现方法的方式将总是导致返回-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);
...

由于personenObservableList<ClubPerson>,因此它不能包含任何Optional<ClubPerson>元素。

尚不清楚为什么您尝试在列表中找到ClubPerson,然后查询该元素的索引,而只是简单地再次访问具有该索引的列表以修改您的ClubPerson ve已经找到。为什么不直接修改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"...