现在我只想知道每一个背后发生了什么
上面引用的循环
1. for (String output : splitted)
{
mylist.add(output);
}
这添加了每个output
字符串来自splitted
数组到mylist
list.
2. for (String output : mylist)
{
System.out.println(output);
mylist = new ArrayList<String>(); //It worked
mylist.add(output);
}
The for
语句由以下产生式控制:
for ( FormalParameter : Expression )
Statement
where 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);
}
Here mylist.iterator()
将返回一个新实例Iterator
type:
public Iterator<E> iterator() {
return new Itr();
}
所以即使你正在创造新的ArrayList
实例并将它们分配给mylist
在每次迭代中,从原始迭代器获得的迭代器mylist
仍将引用原始内容mylist
并将继续迭代原始元素mylist
。迭代器保留对其创建的列表的引用。分配mylist = new ArrayList<String>()
对迭代器处理的数据没有影响,因为它更改了变量mylist
而不是list
itself.
3. for (String output : mylist)
{
System.out.println(output);
mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException
}
下面的语句解释了这种行为。它是复制自Arraylist
doc:
此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间对列表进行结构修改,除了通过迭代器自己的删除或添加方法之外的任何方式,迭代器将抛出 ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒任意、非确定性行为的风险。
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
在迭代列表时,可以通过迭代器自己的删除或添加方法在结构上进行修改。