我可以顺序使用许多listIterator来从Java中的ArrayList中更改或删除列表元素吗?

我依靠列表迭代器来浏览字符列表。这是一个单线程程序,我以4种不同的方法顺序使用listIterator对象。每种方法都有相同的设置:

renderAirplaneList() {
    if (!this.props.airplanes.length) {
        return null;
    }

    const arr = this.props.airplanes || [];

    return arr.map(airplane => {
      return (
        <tr key={airplane.id}>
          <td>{airplane.ID}</td>
          <td>{airplane.term}</td>
          <td>{airplane.actual}</td>
          <td>{airplane["airportToID.city_en"]}</td>
        </tr>
      );
    });
  }

使用此模式,在第二个迭代器上,引发以下异常:

private void myMethod(ArrayList<Integer> input) {
    ListIterator<Integer> i = input.listIterator();
    while (i.hasnext()) {
        Integer in = i.next();
        if (in < 10)
            i.remove();
        else
            i.set(in*in); // because its lucky
    }
}

但是,在查看javadocs时,在抛出的Exceptions中我看不到此Exception,也没有看到完成后关闭迭代器的方法。我使用的listIterator错误吗?我必须多次遍历同一ArrayList,每次有条件地删除或更改每个元素。也许有更好的方法遍历ArrayList,而ListIterator不能最好地解决此用例。

java docs for ListIterator

mystiquec 回答:我可以顺序使用许多listIterator来从Java中的ArrayList中更改或删除列表元素吗?

这在ArrayList Javadoc中有解释,您正在使用(...)时用remove()set()修改列表:

  

此类的Iteratoriterator方法返回的迭代器是快速失败的:如果列表在创建迭代器后的任何时间都进行了结构修改,则除了通过迭代器自己的remove或add方法,迭代器将抛出listIterator 。因此,面对并发修改,迭代器会快速干净地失败,而不会在未来的不确定时间内冒任意,不确定的行为的风险。

,

如果显示的代码显然不是导致异常的代码,甚至无法编译,就很难对问题进行诊断。 remove的{​​{1}}方法不带参数,并且Iterator方法是在set上定义的,但是您的代码仅将变量ListIterator声明为{{ 1}}。

固定版本

i

将毫无问题地运行。常见问题的答案是,每次修改都会使所有现有的迭代器无效,除了在您确实对修改使用迭代器而不是直接使用集合接口时用于进行修改的迭代器。

但是在您的代码中,只有一个迭代器,该迭代器仅创建并用于此操作。只要没有迭代器重复使用相同的集合,无效就不会有问题。先前操作中存在的迭代器无论如何都将被放弃,并且后续操作中使用的迭代器尚不存在。

仍然,它更易于使用

Iterator

相反。与原始代码不同,它进行了两次迭代,但是正如this answer中所述,private void myMethod(ArrayList<Integer> input) { ListIterator<Integer> i = input.listIterator(); while (i.hasNext()) { Integer in = i.next(); if (in < 10) i.remove(); else i.set(in*in); } } 实际上比在性能非常重要的情况下基于迭代器的删除要快。

但是,问题仍然存在。显示的代码不会导致private void myMethod(ArrayList<Integer> input) { input.removeIf(in -> in < 10); input.replaceAll(in -> in*in); } ,因此,无论如何实现此方法,您的实际问题都可能存在,并且仍然存在。

,

我对Java ListIterators的了解不足以回答问题,但看来我在这里遇到了XY问题。通过在原始ArrayList中的每个元素上执行一个函数,使用Java Streams删除元素或将元素映射到新的ArrayList中似乎可以更好地解决该问题。

    private ArrayList<Integer> myMethod(ArrayList<Integer> input) {
        ArrayList<Integer> results = input.stream().filter(
            in -> (in < 10)).collect(Collectors.toCollection(ArrayList::new));

        results = input.stream().map(
            in -> in*in).collect(Collectors.toCollection(ArrayList::new));

        return results;
    }
本文链接:https://www.f2er.com/3169798.html

大家都在问