简体   繁体   English

遍历ArrayList时并发修改异常

[英]Concurrent modification Exception while iterating over ArrayList

The sort method results in a concurrent modification error when i use temp = iterator.next(). 当我使用temp = iterator.next()时,sort方法导致并发修改错误。 Can you please help me resolve the concurrent modification error. 您能帮我解决并发修改错误吗? I gave the code for the entire class but I'm only trying complete the sort method. 我给出了整个类的代码,但是我只是尝试完成sort方法。 Thanks in advance for your help. 在此先感谢您的帮助。

I have to sort all the the arrays in the arraylist. 我必须对arraylist中的所有数组进行排序。

    package HashSet;

            import java.io.InputStream;
            import java.util.ArrayList;
            import java.util.Collections;
            import java.util.ListIterator;
        import java.util.Scanner;

        public class PhoneBook {
            int capacity = 10;
            private ArrayList<PhoneBookEntry>[] buckets;

            public PhoneBook() {
                this(10);
                load();
            }

            public PhoneBook(int size) {
                capacity = size;
                buckets = new ArrayList[size];
                for (int i = 0; i < buckets.length; i++)
                    buckets[i] = new ArrayList<PhoneBookEntry>();
            }

            public int getSize() {
                int tot = 0;
                for (ArrayList<PhoneBookEntry> x : buckets)
                    tot += x.size();
                return tot;
            }

            public boolean add(PhoneBookEntry entry) {
                if (contains(entry))
                    return false;
                int x = Math.abs(entry.hashCode());
                buckets[x % buckets.length].add(entry);
                return true;
            }

            public void load() {
                InputStream is = getClass().getClassLoader().getResourceAsStream(
                        "phone.txt");
                Scanner scan = new Scanner(is);
                while (scan.hasNext())
                    add(new PhoneBookEntry(scan.next(), scan.nextInt()));
                scan.close();
            }

            public void bucketSize() {
                for (int i = 0; i < buckets.length; i++)
                    System.out.println(i + "    " + buckets[i].size());
            }

            public boolean contains(PhoneBookEntry word) {
                int x = Math.abs(word.hashCode());
                return buckets[x % buckets.length].contains(word);
            }

            public int getCapacity() {
                return capacity;
            }

            public int getLongestList() {
                int numb = 0;
                for (ArrayList<PhoneBookEntry> x : buckets)
                    if (x.size() > numb)
                        numb = x.size();
                return numb;
            }

            public void display() {
                for (ArrayList<PhoneBookEntry> x : buckets)
                    System.out.println(x);
            }

            public int getNumberOfNulls() {
                int numb = 0;
                for (ArrayList<PhoneBookEntry> x : buckets)
                    if (x.size() == 0)
                        numb++;
                return numb;
            }

            public String lookup(String name) {
                String numb = name + "'s number not found";
                for (ArrayList<PhoneBookEntry> x : buckets)
                    for (int i = 0; i < x.size(); i++)
                        if (x.get(i).getN().equals(name))
                            numb = name + "'s" + " number is " + x.get(i).getNr();
                return numb;
            }

            public int internalLookUp(String name) {
                int numb = 0;
                for (ArrayList<PhoneBookEntry> x : buckets)
                    for (int i = 0; i < x.size(); i++)
                        if (x.get(i).getN().equals(name))
                            numb = x.get(i).getNr();
                return numb;
            }

            public void sort() {
                String temp = "";
                ArrayList<String> list = new ArrayList<String>();
                ListIterator<String> iterator = list.listIterator();
                final ArrayList<PhoneBookEntry>[] data = buckets.clone();
                for (ArrayList<PhoneBookEntry> x : buckets) {
                    for (int i = 0; i < x.size(); i++) {
                        list.add(x.get(i).getN());
                    }
                    Collections.sort(list);
                    for (int b = 0; b < x.size(); b++) {
                        temp = iterator.next(); //error line
                        x.get(b).setN(temp);
                        x.get(b).setNr(internalLookUp(temp));
                    }
                }
            }

            public static void main(String[] args) {
                PhoneBook phone = new PhoneBook();
                phone.display();
                System.out.println();
                System.out.println("Capacity is " + phone.getCapacity());
                System.out.println();
                System.out.println("Size is " + phone.getSize());
                System.out.println();
                System.out.println("Get longest list " + phone.getLongestList());
                System.out.println();
                System.out.println("Number of Nulls " + phone.getNumberOfNulls());
                System.out.println();
                System.out.println(phone.lookup("Fish"));
                phone.sort();
            }
        }

It looks like your problem is that you're creating an iterator for a list, then modifying the list (adding + sorting), then attempting to use the iterator. 看来您的问题是您正在为列表创建迭代器,然后修改列表(添加+排序),然后尝试使用迭代器。

If you instead created the iterator after this, it should work. 如果您在此之后创建了迭代器,则它将起作用。

eg. 例如。

            for (ArrayList<PhoneBookEntry> x : buckets) {
                for (int i = 0; i < x.size(); i++) {
                    list.add(x.get(i).getN());
                }
                Collections.sort(list);
                ListIterator<String> iterator = list.listIterator(); // Iterator created here
                for (int b = 0; b < x.size(); b++) {
                    temp = iterator.next(); //error line
                    x.get(b).setN(temp);
                    x.get(b).setNr(internalLookUp(temp));
                }

The bug is that you iterate over list while you add to it. 漏洞是您在添加列表时遍历列表 you should not do that. 你不应该那样做。

Here is the javadoc for the ConcurrentModificationException . 这是ConcurrentModificationException的javadoc。

http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception. 如果线程在使用快速失败迭代器迭代集合时直接修改了集合,则迭代器将抛出此异常。

As other posters have said, you should do all sorting and adding before or after using your iterator. 正如其他张贴者所说的那样,您应该在使用迭代器之前或之后进行所有排序和添加。 You can remove an element during iteration, but you must use Iterator.remove() to prevent getting the same exception again. 可以在迭代过程中删除元素,但是必须使用Iterator.remove()来防止再次获得相同的异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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