-1

When I acces to list of list with this function,It make ConcurrentModificationException in second for loop but i don't understand why this Exception is triggered .

 public static List<List<Dico>> weight_term(List<List<Dico>> sublists ,List<String> sinificativ )   
 {

    List<List<Dico>> matrix_node_term = new ArrayList<>();

    List<Dico> list_node =  new ArrayList<>();// a new list for node

    for (List<Dico> sublist : sublists) // to get each sublist List<Dico>
    {
        for (Dico dico : sublist)  // get each Dico in the sublist -->ConcurrentModificationException
        {
            String term =dico.getTerm();            
            int id = dico.getDocId();

            if(sinificativ.contains(term)) // if this term exist in sinificativ erm list
            {
                list_node.add(dico); // it add to list_node 
            }
            else
            {
                list_node.add(new Dico(id,term,0.0)); // it add to list_node with null weigth
            }
        }            
        matrix_node_term.add(list_node); // add each list to list of list 
    }

    return matrix_node_term;
 }

The dico class is used to store term,id of document and the weight of this term in that document :

 public class Dico  implements Comparable 
 {
      private final String m_term;
      private double m_weight;
      private final int m_Id_doc;

      public Dico(int Id_Doc,String Term,double tf_ief ) 
      {
         this.m_Id_doc = Id_Doc;
         this.m_term = Term;
         this.m_weight = tf_ief;   
      }
}

This Exception is triggered without any modification in the sutucte of list or its elements .

Andrey Korneyev
  • 26,353
  • 15
  • 70
  • 71
tommy
  • 139
  • 9
  • The error comes here.... list_node.add(dico)........ while reading a list you are trying to modify it.... and lists are not threadsafe... if you want to do so then first synchronize the list.. – CoderNeji Apr 15 '15 at 09:12
  • 1
    The root cause for `ConcurrentModificationException` is *you are modifying the structure of a collection while iterating through it* – TheLostMind Apr 15 '15 at 09:14
  • Is this a concurrent program? – mtyurt Apr 15 '15 at 09:15
  • 1
    @CoderNeji if you read code befor comment you will see `List list_node = new ArrayList<>();// a new list for node` it's new list i don't change anything in old list – tommy Apr 15 '15 at 09:20
  • @TheLostMind it's probleme i don't modify the structure of list – tommy Apr 15 '15 at 09:22
  • @mtyurt no i iterating through to get value `String term =dico.getTerm(); ` and compare it to other value in `List sinificativ` – tommy Apr 15 '15 at 09:25
  • @TheLostMind there is no modification or the iterated list in the program... – assylias Apr 15 '15 at 09:27
  • 1
    @tommy I think I've worked it out. Were the `List`s in `subList` created using `List.subList`? – Paul Boddington Apr 15 '15 at 09:27
  • @assylias - In one or the other way, the OP is doing that. Reopened the question as it is not an *exact duplicate*. – TheLostMind Apr 15 '15 at 09:31
  • @TheLostMind I don't think he is. `ArrayList.subList` returns lists which throw `ConcurrentModificationException` if the backing `List` is modified structurally except through the `subList`. You don't need any iteration at all for this. – Paul Boddington Apr 15 '15 at 09:33
  • @TheLostMind Yes agreed - but somewhere else, probably in another thread. – assylias Apr 15 '15 at 09:39
  • @assylias No - it's because of `ArrayList.subList`! – Paul Boddington Apr 15 '15 at 09:39
  • @tommy http://stackoverflow.com/help/mcve – assylias Apr 15 '15 at 09:41
  • @pbabcdefp - I suspected that. So I closed it down. But reopened it again as it is not an exact duplicate. Since OP is not using other threads, he should show us how and where this method is being called – TheLostMind Apr 15 '15 at 09:43
  • `List list = new ArrayList<>(Arrays.asList(1, 2, 3)); List subList = list.subList(1, 2); list.add(4); System.out.println(subList.size());` This code throws a `ConcurrentModificationException` with only one thread and no iteration. I expect The OP is holding onto multiple `subList`s created from the same `List` which you shouldn't ever do. – Paul Boddington Apr 15 '15 at 09:44
  • @tommy Can you answer my question? Were the lists in `sublists` created using `List.subList()`? – Paul Boddington Apr 15 '15 at 09:49
  • @pbabcdefp I don't use`List.subList()` ,`sublists` is list ` >` it's creted by my own function `List> split_dico(List list)` i split a list of dico in multiple list by id of document were term is stored . – tommy Apr 15 '15 at 10:08
  • @tommy Can you do `System.out.println(sublists.get(0).getClass());` and tell me what it says? – Paul Boddington Apr 15 '15 at 10:10
  • @pbabcdefp it's `class java.util.ArrayList$SubList` and when i run programe i have `java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1231) at java.util.ArrayList$SubList.listIterator(ArrayList.java:1091) at java.util.AbstractList.listIterator(AbstractList.java:299) at java.util.ArrayList$SubList.iterator(ArrayList.java:1087) at main.application.main(application.java:114)` – tommy Apr 15 '15 at 10:17
  • Exactly. It was created using `subList`. You can't do that. Your `split_dico` method is dividing a `List` up into `subList`s. These `List`s are dangerous. If you make any structural change to the backing `List`, any method you subsequently call on one of the sublists will throw an exception. – Paul Boddington Apr 15 '15 at 10:20
  • @pbabcdefp i don't change any thing in this list i only get value and compare it to other in `List sinificativ`. when i print this list i don't have probleme !! – tommy Apr 15 '15 at 10:28
  • I don't know. You need to give an mcve (see the link provided by @assylias). It's impossible to say exactly where you modify the list without more code (but it is clear that you *are* modifying the list somewhere). However I would say that you **must** make changes to `split_dico`. Don't hold onto references to the lists returned by `subList`. Just copy them instead - ie `subList = new ArrayList<>(list.subList(i, j));` – Paul Boddington Apr 15 '15 at 10:35
  • I use `List> sublists = new ArrayList<>(change); for (int i = 0; i < change; i++) { sublists.add(list.subList(changes[i], changes[i + 1])); }` – tommy Apr 15 '15 at 10:41
  • 1
    Just change that to `List> sublists = new ArrayList<>(change); for (int i = 0; i < change; i++) { sublists.add(new ArrayList(list.subList(changes[i], changes[i + 1]))); }` and the problem should disappear. – Paul Boddington Apr 15 '15 at 10:42
  • 1
    @pbabcdefp tks now i have probleme with Java heap space but i can continu , thank you for your help and your time – tommy Apr 15 '15 at 10:49
  • No worries. Good luck with the heap space problem. I'm completely out of my depth with that. – Paul Boddington Apr 15 '15 at 10:51

1 Answers1

1

Probleme comes from a function used to split List in multiple List:

List<List<Dico>> sublists = new ArrayList<>(change);

for (int i = 0; i < change; i++)
{ 
   sublists.add(list.subList(changes[i],changes[i + 1]));
}

A solution comes from pbabcdefp

List<List<Dico>> sublists = new ArrayList<>(change);
for (int i = 0; i < change; i++)
{
  sublists.add(newArrayList<Dico>(list.subList(changes[i], changes[i + 1])));
}

thank you for your help

Community
  • 1
  • 1
tommy
  • 139
  • 9