每个循环工作的 Java

标签 java loops foreach

我正在执行某项任务,根据我的说法偶然做错了什么但是代码执行并提供了正确的结果。我有点惊讶,并且想知道每个循环的所有这些是如何工作的。 示例(示例程序),

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/

相关文章:

php - 处理两个多维数组并跳过最终输出中共享值的数组

Java TreeMap 放置方法

azure - 如何在Azure逻辑应用程序中动态更改GET请求

java - java将数组值左移

php - 为循环中的每个表行赋予唯一类

java - 如何避免嵌套的 forEach 调用?

php - 如何在PHP中强制重置foreach

java - response.sendRedirect() 未正确重定向

java - 使用 BeanUtils 设置 setter 值

java - java中的可变4维元组