Java 为什么arrayList没有在最后一个元素上迭代?
我尝试了以下两种情况:Java 为什么arrayList没有在最后一个元素上迭代?,java,arraylist,collections,Java,Arraylist,Collections,我尝试了以下两种情况: ArrayList arrayList = new ArrayList(); arrayList.add("1"); arrayList.add("2"); arrayList.add("3"); Iterator iterator = arrayList.iterator(); while (iterator.hasNext()) { String value = (String) iterator.n
ArrayList arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("1")) {
arrayList.remove(0);
}
}
第一个场景输出是:
---->1
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at Test.main(Test.java:83)
可能是因为我在迭代集合时试图修改集合而导致了ConcurrentModificationException
异常
在第二个场景中,我将if()
条件从value.equals(“1”)
更改为value.equals(“2”)
,程序不会抛出任何错误
ArrayList arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
arrayList.remove(0);
}
}
第二个场景输出是:
---->1
---->2
在这两种情况下,我的程序都没有到达第三个元素(值:3)
您能帮我理解这个问题吗?问题是您正在从列表中删除在索引0处显示的元素。使用iterator.remove()方法,而不是从列表中删除。欲了解更多信息,请阅读 程序代码-
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
为什么列表不返回最后一个元素?
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
回答-
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
您正在从列表中删除元素,并且已经对同一列表执行迭代器操作。在iterator.hasnext()的末尾,方法返回false,这样就不会得到最后一个元素
如果您想查看演示,请在下面的示例代码中运行-
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
arrayList.remove(0);
}
}
System.out.println("ArrayList : "+arrayList);
输出-
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
---->一,
---->二,
ArrayList:[2,3]
输出-
List arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
String value = (String) iterator.next();
System.out.println("---->" + value);
if (value.equals("2")) {
iterator.remove();
}
}
---->一,
---->二,
---->三,
ArrayList:[1,3]
对集合进行迭代时,应使用迭代器删除元素:
iterator.remove()
在第二个代码中,如下所示:
if (value.equals("2")) {
arrayList.remove(0);
}
删除列表的第一个元素。列表的大小为2个元素。迭代器实现会考虑列表的大小,以了解它是否有下一个元素:
public class ArrayList<E> extends AbstractList<E>
...
private class Itr implements Iterator<E> {
public boolean hasNext() {
return cursor != size;
}
}
公共类ArrayList扩展了AbstractList
...
私有类Itr实现迭代器{
公共布尔hasNext(){
返回光标!=大小;
}
}
由于迭代了两个元素,并且由于删除了列表中的一个元素,列表现在的大小为2,因此迭代器认为它没有下一个要迭代的元素。如果使用迭代器删除当前元素,则不会产生这种副作用。
我假设您仅在第一种情况下遇到问题,因为您试图删除迭代器所指向的元素。事实上,第二个场景成功了,因为您删除了第一个
arraylist
元素,此时迭代器没有指向该元素
(另外,我同意所有关于如何通过显示代码片段来解决问题的各种和未来的答案,我只是向您解释了会发生什么)发生
ConcurrentModificationException
是因为您删除了相同的元素(在索引0处)循环的当前迭代正在读取(值为=“1”的迭代)。在第二种情况下,您没有看到异常,因为您正在删除索引0处的元素,但正在读取索引1处的元素(值为=“2”的元素)。除非使用支持并发性的集合之一(请参见java.util.concurrent
package),否则在读取元素时不能同时删除该元素
您在迭代列表时正在删除一个元素(
remove(0)
),这会将列表的末尾向左移动一个。因此,下次检查iterator.hasNext()时,它将返回false,并且原始的第三个元素永远不会得到处理。通过在调试模式下运行两段代码,我发现如下内容
第一种情况:
从arraylist保存的元素:
执行删除命令后:
ConcurrentModificationException
在下面一行抛出
String value = (String) iterator.next();
第二种情况:
ArrayList
将与第二个链接相同
打印2后,控件从
while (iterator.hasNext())
as
iterator.hasNext()
=null。因此它是安全的。arrayList.remove(0)代码>是您的问题所在。使用迭代器
对象来删除元素。@Jonk我知道调用迭代器对象的remove方法可以避免错误。但我想理解为什么在第二个场景中第三个元素没有达到它?这是因为在索引0处删除元素后,3
变为第二个元素,因此已经被认为是迭代的;它不会抛出异常,因为fail fast行为无法保证-请参阅可能的重复项。我知道通过调用迭代器对象的remove方法可以避免错误。但我想理解为什么在第二个场景中的第三个元素没有达到它?@Keval Pithva-因为您正在从列表中删除元素,并且已经对同一个列表执行迭代器操作。在结束时,iterator.hasnext()方法返回false,因此您不会得到最后一个元素。iterator.hasnext()方法是否在每次迭代集合时都检查列表的大小?是。它在ArrayList的实现中。我把它贴了。