2
votes

I have an issue removing the 1st and 2nd element of my list even by using the iterator.

I have read the following threads but can't fix my issue (those were the most relevant but I checked other material as well):

ConcurrentModificationException when trying remove element from list

Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop

So my code looks like this:

List<List<String>> list = cnf.read();
List<List<String>> nlist = new ArrayList<>();
for (List<String> l : list) {
    if (l.size() <= 3) {
        nlist.add(l);
    } else {
        int size = l.size();
        while (size > 3) {
            List<String> three = l.subList(0, 2);
            three.add("Y" + (count++));
            //Iterator itr = l.iterator();
            ListIterator itr = l.listIterator();
            int v = 0;
            while (itr.hasNext()) {
                itr.next();
                if (v == 0 || v == 1) {
                    itr.remove();
                    v++;
                }
            }
            l.add(0, "Y" + (count++));
            size--;
            nlist.add(three);
        }
        nlist.add(l);
    }
}
for (List<String> l : nlist) {
    System.out.println(l.toString());
    System.out.println(l.size());
}

I get a ConcurrentModificationException at the print statement here :

System.out.println(l.toString());

I tried using iterators for my 2 for loops as well but It doesn't seem to make a difference! I am new to posting questions so let me know If I am doing it right! Thank you.

1
Are you familiar with interface java.util.ListIterator? According to its javadoc, it allows modification of the list while traversing it.Abra
@Abra Yes! I am using the iterator to do itr.remove(). This should allow me to remove the items I want from the list. However, It causes an exception. My guess is that it's because it is located in another loop (nested) so it's causing issues. I don't know how to fix it.Mamoun Debbarh
The code you posted does not contain ListIterator.Abra
@Abra So the line: Iterator itr = l.iterator(); Is not a ListIterator but a simple Iterator? I am checking it now to find a solution. It might be a lead.Mamoun Debbarh
Even by using ListIterator it = l.listIterator();. I get the same exception. As I understood from the following post: techdifferences.com/… The main difference between the 2 methods is that list iterator allows you to modify and element and traverse the list in both directions.Mamoun Debbarh

1 Answers

0
votes

After A long debugging, here is the solution.

The sublist function passes by reference and not by value, a sublist created by ArrayList.subList call keeps a reference to the original list and accesses its elementData array directly.

For this reason, when adding an element to the "three" list, we alter the state of the original list. this happens here:

three.add("Y" + (count++));

A way of fixing it for this specific case is to create and initialize the "three" list the following way:

                String one = l.get(0);
                String two = l.get(1);
                List<String> three = new ArrayList<>();
                three.add(one);
                three.add(two);
                three.add("Y" + (count));

This allows us to manipulate our lists without getting Concurrency Exceptions (ConcurrentModificationException). However, if you are manipulating big lists, I would suggest you use another less hardcoded method for list creation.

I will mark this thread as answered and hope it helps people.