NoSuchElementException 发生是因为 AbstractList 中的 Iterator 调用 hasNext() 如下
public boolean hasNext() {
return cursor != size();
}
但是在 List 上执行 remove 操作后,调用 size() 的结果会发生变化。因此我将 size 设为 final int listSize。
NoSuchElementException 发生是因为 AbstractList 中的 Iterator 调用 hasNext() 如下
public boolean hasNext() {
return cursor != size();
}
但是在 List 上执行 remove 操作后,调用 size() 的结果会发生变化。因此我将 size 设为 final int listSize。
我在本地测试了我的提交。但没有在提交中添加测试。如果需要,我将在将来添加测试。
从#3790 的讨论来看,听起来,如果有的话,我们想要hasNext()
抛出一个ConcurrentModificationException
。
@cpovirk 嗨,我已查看了讨论。但我认为预期的行为不应该引发异常。
根据讨论,他们对iter.hasNext()为何为真感到困惑。实际上,这是因为Partition类使用了超类AbstractList中的Iterator。而AbstractList类中的hasNext()函数并不完善。它们已在子类ArrayList中进行了优化。请在下面查看
这是AbstractList类中的hasNext。它调用size()函数
public boolean hasNext() {
return cursor != size();
}
这是ArrayList类中的hasNext。它使用值 size。文档说它是AbstractList.Itr 的优化版本。我在 JDK1.8 中看到了这个
public boolean hasNext() {
return cursor != size;
}
当使用函数size()时,每次程序调用hasNext()。hasNext()会调用size(),然后size 的值会被重新计算。回到 #3570 的代码,当程序执行removeall()时,重新计算的 size 会是 0,但是游标是 1。所以hasNext()返回 true。
示例代码见#3570
for(List<Integer> l : ll){
l.removeAll(elementExclude);
}
因此我引入了listsize来保存该值,以确保它只被计算一次。
我还测试了下面的代码。我使用 ArrayList 作为容器,然后执行相同的removeAll操作。没有抛出任何异常。所以,我认为分区的行为应该相同
List<Integer> list = new ArrayList();
list.add(1);
List<Integer> elementExclude = new ArrayList();
elementExclude.add(1);
List<List<Integer>> ll = new ArrayList();
ll.add(list);
for(List<Integer> l : ll){
l.removeAll(elementExclude);
}
拼写错误:3790,不是 3570
让我们整合其他帖子中的讨论。如果就该怎么做达成一致,我们可以重新打开此帖子(或新的 PR)。
@cpovirk 好的,我会在 #3790 中与他们讨论我的想法。无论如何,谢谢