简体   繁体   中英

What is wrong with my code in java iterators

I am writing a file explorer

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

        }

When the code reaches to the it.remove(); I get the following error:

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)

Quoting the Docs of remove:

Removes from the list the last element that was returned by next() or previous() (optional operation). This call can only be made once per call to next or previous. It can be made only if add(E) has not been called after the last call to next or previous .

Additional information quoted from the docs regarding the remove method:

Note that the remove() and set(Object) methods are not defined in terms of the cursor position; they are defined to operate on the last element returned by a call to next() or previous().

So therefore if you call add(E) within the iteration you cannot call remove() also.

I would put the remove() method in the else statement:

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

that way It will not be called if you call add(E)

However the remove method is optional as you are allowed to continually call the next() method without making calls to remove() . So you could just omit it completely which may be your desired result.

Thanks @chancea.

I had to change my code to the following lines to implement BFS search:

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

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM