1

I have a linkedlist where each element has key and value(ArrayList<dataStructure>). I want to merge the elements having same key.

    Iterator<CElem> oItr = linkedList.iterator();
    {
        while (oItr.hasNext())
        {
            CElem outer = oItr.next();              
            Iterator<CElem> iItr = linkedList.iterator();
            {
                while (iItr.hasNext())
                {
                    CElem inner = iItr.next();
                    if (outer.equals(inner))
                        continue;

                    if (outer.getKey().equals(inner.getKey()))
                    {
                        outer.getValues().addAll(inner.getValues());
                        iItr.remove();
                    }
                }
            }
        }
    }

Though I am using the iterators remove methog getting a java.util.ConcurrentModificationException. What should be changed to get rid of this.

4

5 Answers 5

2

You remove element with one of your iterators, thus the second of them does not know about this removal and ConcurrentModificationException is thrown

BTW:

you should consider using some multimap in place of list that is having key-values pairs

Sign up to request clarification or add additional context in comments.

Comments

1

Add the elements you want to remove in another List and then loop in that list at the end to remove these elements.

Alternatively, use a Map/Set.

Comments

1

Both your iterators are traversing the linked list

Iterator<CElem> oItr = linkedList.iterator();
....
Iterator<CElem> iItr = linkedList.iterator();

probably iItr should be for the inner array list?

UPDATE Scratch above answer I misread the question. The challenge though is that you have two iterators traversing the list, so while you use one iterator's remove() method, the other still detects the concurrent modification.

Normally, to remove duplicates from a list, you can just run them through a Set (e.g. a HashSet) but that won't work for you as it's only key duplication, not the entire member of the list.

I'd take an approach where I try to find and capture the duplicated keys and their values in a separate list and then merge in and remove the duplicates as a separate step.

Comments

0

The problem is that when you use the iItr.remove() it modifies the list, which iItr is happy with because it knows what changed, but oItr isn't. There are three possible solutions to this that I can see:

  1. Switch to a concurrent list (e.g. ConcurrentLinkedQueue - but see then answers at Lock-Free Concurrent Linked List in Java for warnings about this)
  2. Switch to a set structure, e.g. TreeSet, which will keep your items unique automatically (but won't preserve their order)
  3. Make sure you don't use the other iterator after removing from one of them -- you could do this by switching which element you are removing, i.e. change iItr.remove() to:

     oItr.remove();
     break;
    

This would cause the first instance of each key to be removed, rather than subsequent ones, which might not be the behaviour you want -- in that case you could try iterating over the lists backwards.

Comments

0

Will this work?

 Iterator<CElem> oItr = linkedList.iterator();
    {
        while (oItr.hasNext())
        {
            CElem outer = oItr.next();              
            Iterator<CElem> iItr = linkedList.iterator();
            {
                while (iItr.hasNext())
                {
                    CElem inner = iItr.next();
                    if (outer.equals(inner))
                        continue;

                    if (outer.getKey().equals(inner.getKey()))
                    {
                        inner.getValues().addAll(outer.getValues());
                        outer.remove();
                        break;
                    }
                }
            }
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.