【问题标题】:Java throws IndexOutOfBounds when editing observableListJava 在编辑 observableList 时抛出 IndexOutOfBounds
【发布时间】:2023-04-11 01:02:01
【问题描述】:

我的老师告诉我,当我更新 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)

【问题讨论】:

  • 使用前检查index...

标签: java indexoutofboundsexception observablelist


【解决方案1】:

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

也就是说,您当前实现方法的方式将总是导致返回 -1。注意indexOf的签名;它接受Object,而不是E。这意味着您可以将任何您想要的对象传递给该方法,并且您的代码将编译。现在看看Stream.findFirst() 的返回类型——它返回Optional&lt;T&gt;。换句话说,您的代码相当于:

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

由于personenObservableList&lt;ClubPerson&gt;,它不能包含任何Optional&lt;ClubPerson&gt; 元素。

不清楚为什么您尝试在列表中找到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"...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-10
    • 2019-01-05
    • 2014-04-03
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    相关资源
    最近更新 更多