我在java迭代器中的代码有什么问题

时间:2015-02-04 20:15:49

标签: java file iterator

我正在编写文件资源管理器

ArrayList<File> folders = new ArrayList<File>(Arrays.asList(parent
                .listFiles(filter)));

ListIterator<File> it = folders.listIterator();

        while (it.hasNext()) {

            File file = it.next();

            if (file.isDirectory())
            {
                ArrayList<File> subFolders = new ArrayList<File>(
                        Arrays.asList(file
                                .listFiles(filter)));
                for (File sub : subFolders) {
                    it.add(sub);
                }
            }
            else
            {
                mediaFiles.add(file);
            }

            it.remove();

        }

当代码到达it.remove();时,我收到以下错误:

02-04 23:32:47.670: E/AndroidRuntime(20230):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-04 23:32:47.670: E/AndroidRuntime(20230):    at dalvik.system.NativeStart.main(Native Method)
02-04 23:32:47.670: E/AndroidRuntime(20230): Caused by: java.util.ConcurrentModificationException
02-04 23:32:47.670: E/AndroidRuntime(20230):    at java.util.AbstractList$SimpleListIterator.remove(AbstractList.java:71)

2 个答案:

答案 0 :(得分:9)

引用删除的Docs

  

从列表中删除next()或previous()(可选操作)返回的最后一个元素。此呼叫只能在每次呼叫下一次或上一次时进行一次。 只有在最后一次调用下一个或上一个后未调用add(E)时才能进行此操作。

有关删除方法的文档中引用的其他信息:

  

请注意,remove()和set(Object)方法没有根据光标位置定义;它们被定义为对next()或previous()的调用返回的最后一个元素进行操作。

因此,如果您在迭代中致电add(E),则无法再致电remove()

我会将remove()方法放在else语句中:

else
{
    mediaFiles.add(file);
    it.remove();
}

那样如果你拨打add(E)

,就不会被调用

但是,移除方法是可选,因为您可以在不调用next()的情况下不断调用remove()方法。所以你可以完全省略它,这可能是你想要的结果。

答案 1 :(得分:0)

谢谢@chancea。

我不得不将我的代码更改为以下行以实现BFS搜索:

    Queue<File> queue = new LinkedList<File>();
    queue.add(parent);

    ArrayList<File> mediaFiles = new ArrayList<File>();

    while (!queue.isEmpty()) {
        File file = queue.remove();

        if (file.isDirectory())
        {
            ArrayList<File> subFolders = new ArrayList<File>(
                    Arrays.asList(file
                            .listFiles(filter)));
            for (File sub : subFolders) {
                queue.add(sub);
            }
        }
        else
        {
            mediaFiles.add(file);
        }

    }