Java为每个循环工作 [英] Java for each loop working

查看:152
本文介绍了Java为每个循环工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做某些工作,<偶然根据我做错事,但是代码执行并提供了正确的结果。我感到有些惊讶,并且想到每个循环的所有这些是如何工作的。
示例(示例程序),

  public static void main(String [] args)
{
String myInput =你好,你好吗;
String [] splitted = myInput.split(,);
列表< String> mylist = new ArrayList< String>();
for(String output:splitted)
{
mylist.add(output);


$ b for(String output:mylist)
{
System.out.println(output);
mylist = new ArrayList< String>(); //它工作
mylist.add(输出);


(String output:splitted)
{
mylist.add(output);


(String output:mylist)
{
System.out.println(output);
mylist.add(输出); //在这行之后,抛出异常java.util.ConcurrentModificationException
}

}

我很想知道,在搜索的时候,我发现另一个帖子说如果我们使用迭代器的方法,我们可以从列表中删除元素,所以我试过了,

< pre $ 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(); / /它的工作,但如果我用同样的东西从原始列表中删除元素,它抛出异常。





$ b现在我只想知道引用的每个循环的每个后面发生了什么上面。

我想知道技术方​​面,我知道我不能修改每个循环中的集合,但在某些情况下,上面说明了为什么?

解决方案


现在我只想知道上面引用的每个
循环的每个后面发生了什么



  1. for(String output:splitted)
{
mylist 。新增(输出);



$ b

这增加了每个输出 splitted 数组到 mylist 列表中的字符串。

  2。 for(String output:mylist)
{
System.out.println(output);
mylist = new ArrayList< String>(); //它工作
mylist.add(输出);

语句的是由以下生产:
$ b $ pre $ for(FormalParameter:Expression)
语句
$ b $ 表达式必须是 java.lang中的一个实例.Iterable 或者一个数组。所以这个对于:每个循环都相当于这个:

  Iterator<串GT; iterator = mylist.iterator(); 
while(iterator.hasNext()){
System.out.println(output);
mylist = new ArrayList< String>(); //它工作
mylist.add(输出);



$ b

这里 mylist.iterator()将会返回一个新的 Iterator 类型实例:

  public迭代< E  - 代替; iterator(){
return new Itr();





$ b所以即使你正在创建新的 ArrayList
code>实例并在每次迭代时将它们分配给 mylist ,从原来的 mylist 获得的迭代器仍然会引用原始的 mylist ,并将继续遍历原始 mylist 的元素。迭代器保持对它创建的列表的引用。 mylist = new ArrayList ()对迭代器的数据没有影响,因为它改变了变量 mylist 而不是 list 本身。

  3。 for(String output:mylist)
{
System.out.println(output);
mylist.add(输出); //在这行之后,抛出异常java.util.ConcurrentModificationException
}

这种行为。它是从 Arraylist doc:

复制的
$ b


这个类的迭代器返回的迭代器和listIterator方法是快速失败的:如果在迭代器创建后的任何时候,结构性地修改列表,除了通过迭代器自己的remove或add方法以外,迭代器将抛出一个ConcurrentModificationException异常。因此,在并发修改的情况下,迭代器将很快并且干净地失败,而不是在将来某个未定的时间冒着任意的,不确定的行为冒险。



  4。 for(Iterator iterator2 = mylist.iterator(); iterator2.hasNext();)
{
String string =(String)iterator2.next();
System.out.println(string);
iterator2.remove(); / /它的工作,但如果我用同样的东西从原始列表中删除元素,它抛出异常。





$ b

上面的语句也解释了这个for循环的行为: list 可以通过迭代器自己的remove或add方法进行结构修改,同时迭代整个列表。


I was working on certain task, when incidentally did something wrong according to me but the code executed and provided correct result. I was little surprised and had question in mind how all these for each loop works. Example (sample program),

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
    }

}

I was curious to know and while searching I found one more post that said we can remove elements from list if we used iterator approach, So I tried,

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.
}

Now I just want to know what is happening behind the every for each loop quoted above.
I want to know the technical aspect, I know I can not modify the collection in for each loop but in some case stated above it worked why?

解决方案

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);
    }

This adds each output String from splitted array to the mylist list.

2. for (String output : mylist) 
{
      System.out.println(output);
      mylist = new ArrayList<String>(); //It worked 
      mylist.add(output);
}

The for statement is governed by the following production:

for ( FormalParameter : Expression )
            Statement

where Expression must be an instance of java.lang.Iterable, or an array. So this for:each loop is equivalent to this:

Iterator<String> iterator = mylist.iterator();
while (iterator.hasNext()) {
    System.out.println(output);
    mylist = new ArrayList<String>(); //It worked 
    mylist.add(output);
}

Here mylist.iterator() will return a new instance of Iterator type:

public Iterator<E> iterator() {
        return new Itr();
}

So even if you are creating new ArrayList instances and assigning them to mylist on each iteration, the iterator obtained from the original mylist will still have a reference to the original mylist and will keep iterating through the elements of original mylist. The iterator keeps a reference to the list it was created on. The assignment mylist = new ArrayList<String>() has no effect on the data that the iterator works on because it changes the variable mylist and not the list itself.

3. for (String output : mylist) 
    {
        System.out.println(output);             
        mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException
    }

Below statement explains this behavior. It is copied from Arraylist doc:

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.
}

The above statement also explains the behavior of this for loop: the list can be structurally modified by the iterator's own remove or add methods while iterating through the list.

这篇关于Java为每个循环工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆