Java 在编辑 observableList 时抛出 IndexOutOfBounds

标签 java indexoutofboundsexception observablelist

我的老师教我,当我更新 Observable List 中的对象时,它会自动检测更改并通知观察者。但是,当我尝试更新列表中的某个人时,它会抛出索引越界异常。我不知道出了什么问题。

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)

最佳答案

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"...

关于Java 在编辑 observableList 时抛出 IndexOutOfBounds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56115123/

相关文章:

java - 泛型:如何处理类层次结构中的多个有界类型

带有 cellfactory 的 javafx ComboBox 不显示所选项目

java - 我有一个代表时间(以毫秒为单位)的 Long 列表。如何创建一个 ListView,在显示长整型之前将它们格式化为 MM :SS. LLL?

java - 由于使用了 Observable List,Gson 无法反序列化

java - 将上传文件的文件名存储在数据库java中

java - jdbcTemplate 批量执行多条sql语句

java - 从文件读取时获取 arrayindexoutofbounds

java - 数组索引超出 JSwing 和 2D 数组的范围

java - 如何为字段创建具有枚举类型的对象

java - ArrayIndexOutOfBoundsException 错误,虽然我不使用数组