我正在执行某项任务,根据我的说法偶然做错了什么但是代码执行并提供了正确的结果。我有点惊讶,并且想知道每个循环的所有这些是如何工作的。 示例(示例程序),
public static void main( String[] args )
{
String myInput = "hello , hi , how are you ";
String[] splitted = myInput.split(",");
List<String> mylist = new ArrayList<String>();
for (String output : splitted)
{
mylist.add(output);
}
for (String output : mylist)
{
System.out.println(output);
mylist = new ArrayList<String>(); //It worked
mylist.add(output);
}
for (String output : splitted)
{
mylist.add(output);
}
for (String output : mylist)
{
System.out.println(output);
mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException
}
}
我很想知道,在搜索时我发现了另一个帖子说如果我们使用迭代器方法我们可以从列表中删除元素,所以我尝试了,
for (String output : splitted)
{
mylist.add(output);
}
for (Iterator iterator2 = mylist.iterator(); iterator2.hasNext();)
{
String string = (String) iterator2.next();
System.out.println(string);
iterator2.remove(); //It worked but if I used the same thing to remove element from original list it threw exception.
}
现在我只想知道上面引用的 every for each 循环背后发生了什么。
我想知道技术方面,我知道我不能为每个循环修改集合,但在上面提到的某些情况下它起作用了,为什么?
最佳答案
Now I just want to know what is happening behind the every for each loop quoted above
1. for (String output : splitted)
{
mylist.add(output);
}
这将添加每个 output
来自 splitted
的字符串数组到 mylist
列表。
2. for (String output : mylist)
{
System.out.println(output);
mylist = new ArrayList<String>(); //It worked
mylist.add(output);
}
for
语句受以下产生式约束:
for ( FormalParameter : Expression )
Statement
哪里Expression
必须是 java.lang.Iterable
的实例,或者一个数组。所以这个for:each
循环等同于:
Iterator<String> iterator = mylist.iterator();
while (iterator.hasNext()) {
System.out.println(output);
mylist = new ArrayList<String>(); //It worked
mylist.add(output);
}
在这里mylist.iterator()
将返回 Iterator
的新实例输入:
public Iterator<E> iterator() {
return new Itr();
}
因此,即使您正在创建新的 ArrayList
实例并将它们分配给 mylist
在每次迭代中,从原始 mylist
获得的迭代器仍将引用原始 mylist
并将继续迭代原始 mylist
的元素.迭代器保留对创建它的列表的引用。作业mylist = new ArrayList<String>()
对迭代器处理的数据没有影响,因为它更改了变量 mylist
而不是 list
本身。
3. for (String output : mylist)
{
System.out.println(output);
mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException
}
下面的语句解释了这种行为。复制自 Arraylist
文档:
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
4. for (Iterator iterator2 = mylist.iterator(); iterator2.hasNext();)
{
String string = (String) iterator2.next();
System.out.println(string);
iterator2.remove(); //It worked but if I used the same thing to remove element from original list it threw exception.
}
上面的语句也解释了这个for循环的行为:list
可以在遍历列表时通过迭代器自己的 remove 或 add 方法进行结构修改。
关于每个循环工作的 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19511956/