首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IndexOutOfBounds编辑observableList时抛出observableList

IndexOutOfBounds编辑observableList时抛出observableList
EN

Stack Overflow用户
提问于 2019-05-13 15:05:58
回答 1查看 300关注 0票数 1

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

代码语言:javascript
复制
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());
    }

这是错误的路径:

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-13 15:45:17

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

尽管如此,您当前实现方法的方式将始终是,将导致返回-1。注意indexOf的签名;它接受Object,而不是E。这意味着您可以将任何想要的对象传递给该方法,您的代码就会编译。现在看看Stream.findFirst()的返回类型(https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/stream/Stream.html#findFirst(%29)—it返回Optional<T> )。换句话说,您的代码相当于:

代码语言:javascript
复制
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)

代码语言:javascript
复制
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() (Java10+)的内容。

代码语言:javascript
复制
ClubPerson p = personen.stream().filter(p -> p.getId() == currentLid.getId())
        .findFirst()
        .orElseThrow(); // throws NoSuchElementException if element not found
// set properties of "p"...
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56115123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档