IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Problème de Remove dans une Linked List et fonction récursive


Sujet :

Langage Java

  1. #1
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut Problème de Remove dans une Linked List et fonction récursive
    Bonjour, voici le problème:
    Je veux enlever l'élément M de la liste L sachant que L est une liste de ModuleTree, c'est à dire une structure arborescente définie comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class ModuleTree{
    	boolean leaf = false;
    	LinkedList children=new LinkedList();
    	String label="";
    	Vertex representant=null;
    Donc L ressemble à ça :
    [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    Ci dessus par exemple on veut enlever le module ||(770 : SHS1) (1 : YDL225W)), il faut donc faire une fonction récursive. Voilà à quoi j'ai pensé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    public static LinkedList listeSansM(LinkedList L, ModuleTree M){
     
             for(Iterator IT=L.iterator();IT.hasNext(); ){
              ModuleTree Mtmp = (ModuleTree) IT.next();
     
              System.out.println("Mtmp : "+Mtmp.toString());
              System.out.println("M : "+M.toString());
              System.out.println("L= "+L.toString());
                if(Mtmp.equals(M))
               {
                 L.remove(M);
                }else{
                 System.out.println("Mtmp.isLeaf?"+Mtmp.toString()+" : "+Mtmp.isLeaf());
                   if(!Mtmp.isLeaf()){
                    LinkedList Ltmp=Mtmp.getChildren();
                    System.out.println("enfant : "+Ltmp.toString());
                    listeSansM(Ltmp,M);
                    }
                  }
             }
     
             System.out.println("Lfinal= "+L.toString());
             return L;
            }
    Mais ça semble boucler, voilà l'affichage que j'obtiens jusqu'à l'erreur :

    Mtmp : (111 : CDC12)
    M : || ( (770 : SHS1) (1 : YDL225W))
    L= [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    Mtmp.isLeaf? (111 : CDC12) : true
    Mtmp : (270 : BNI4)
    M : || ( (770 : SHS1) (1 : YDL225W))
    L= [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    Mtmp.isLeaf? (270 : BNI4) : true
    Mtmp : * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3))
    M : || ( (770 : SHS1) (1 : YDL225W))
    L= [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    Mtmp.isLeaf?* (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)) : false
    enfant : [|| ( (770 : SHS1) (1 : YDL225W)), (17 : CDC11), (803 : GIN4), (723 : CDC3)]
    Mtmp : || ( (770 : SHS1) (1 : YDL225W))
    M : || ( (770 : SHS1) (1 : YDL225W))
    L= [|| ( (770 : SHS1) (1 : YDL225W)), (17 : CDC11), (803 : GIN4), (723 : CDC3)]
    Ca serait le remove qui ne passe pas ? Me suis-je plantée dans ma récursion ?
    Merci pour vos remarques et solutions que vous pourrez m'apporter...

  2. #2
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut La récursivité en cause
    J'ai un peu modifié le code et surtout changé les commentaires pour essayer de comprendre pourquoi ça ne fonctionne pas :

    public static void listeSansM(LinkedList L, ModuleTree M){

    System.out.println("L Début = "+L.toString());

    for(Iterator IT=L.iterator();IT.hasNext(); ){
    ModuleTree Mtmp = (ModuleTree) IT.next();
    System.out.println("--------------------------------");
    System.out.println("En entrée du for : L = "+ L.toString());
    System.out.println(" M = "+ M.toString());
    System.out.println("--------------------------------");
    if(Mtmp.equals(M)){
    System.out.println("La liste avant retrait de M : "+L.toString());
    L.remove(M);
    System.out.println("La liste après retrait de M : "+L.toString());
    }else{
    if(!Mtmp.isLeaf()){
    listeSansM(Mtmp.getChildren(),M);
    }
    }
    }
    System.out.println("L Fin = "+L.toString());
    }
    Voilà le résultat :

    L Début = [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    --------------------------------
    En entrée du for : L = [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    M = || ( (770 : SHS1) (1 : YDL225W))
    Mtmp = (111 : CDC12)
    --------------------------------
    --------------------------------
    En entrée du for : L = [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    M = || ( (770 : SHS1) (1 : YDL225W))
    Mtmp = (270 : BNI4)
    --------------------------------
    --------------------------------
    En entrée du for : L = [ (111 : CDC12), (270 : BNI4), * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3)), (438 : NFI1), (677 : CDC10)]
    M = || ( (770 : SHS1) (1 : YDL225W))
    Mtmp = * (|| ( (770 : SHS1) (1 : YDL225W)) (17 : CDC11) (803 : GIN4) (723 : CDC3))
    --------------------------------
    L Début = [|| ( (770 : SHS1) (1 : YDL225W)), (17 : CDC11), (803 : GIN4), (723 : CDC3)]
    --------------------------------
    En entrée du for : L = [|| ( (770 : SHS1) (1 : YDL225W)), (17 : CDC11), (803 : GIN4), (723 : CDC3)]
    M = || ( (770 : SHS1) (1 : YDL225W))
    --------------------------------
    La liste avant retrait de M : [|| ( (770 : SHS1) (1 : YDL225W)), (17 : CDC11), (803 : GIN4), (723 : CDC3)]
    La liste après retrait de M : [ (17 : CDC11), (803 : GIN4), (723 : CDC3)]
    ...et puis pouf ! plantage... Donc le remove fonctionne correctement... c'est ma récursion qui pèche... mais où ????

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par GDMINFO
    ...et puis pouf ! plantage...
    En général lorsqu'une application Java plante on a un joli stacktrace bien utile pour trouver l'origine du problème...

    a++

  4. #4
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    Oui, effectivement...

    Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:617)
    at java.util.LinkedList$ListItr.next(LinkedList.java:552)
    at ModuleTree.listeSansM(ModuleTree.java:362)
    at ModuleTree.listeSansM(ModuleTree.java:374)
    at DecompositionH.decompositionHomogene(DecompositionH.java:557)
    at Main.main(Main.java:291)
    Java Result: 1
    Est ce que cela veut dire que je modifie en même temps une même structure ? Comment l'éviter ?

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Les ConcurrentModificationException surviennent lorsque tu modifies une collection pendant que tu la parcours avec un itérateur.

    Tu dois utiliser la méthode remove() de ton itérateur et non pas directement celle de ta liste.

    a++

  6. #6
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    Je suis désolée, je ne comprend pas bien ce que cela veut dire... Comment un itérateur peut il avoir une méthode ?

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par GDMINFO
    Comment un itérateur peut il avoir une méthode ?
    Ben l'interface Iterator propose une méthode remove()...


    Tu ne peux pas modifier la liste pendant son parcours via l'itérateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(Iterator IT=L.iterator();IT.hasNext(); ) {
    	ModuleTree Mtmp = (ModuleTree) IT.next();
    	if(Mtmp.equals(M)) {
    		L.remove(Mtmp); // Plante car tu modifies la liste pendant son parcours par l'itérateur
    	}
    }
    Car si tu modifies la liste alors l'itérateur doit prendre en compte les modifications afin d'éviter des incohérences. Or cela peut s'avérer assez complexe (et plus ou moins selon le type d'implémentation de la liste). Ainsi pour éviter de se retrouver dans des états incohérents qui pourrait poser des problèmes difficilement décelable, les itérateurs sont "fail-fast", c'est à dire qu'il plante rapidement dès qu'il détecte une modification sur la liste en dehors de l'itérateur...

    Il faut donc utiliser l'itérateur pour modifier la liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(Iterator IT=L.iterator();IT.hasNext(); ) {
    	ModuleTree Mtmp = (ModuleTree) IT.next();
    	if(Mtmp.equals(M)) {
    		IT.remove(); // OK : la modif passe par l'itérateur
    	}
    }
    a++

  8. #8
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    Merci
    Je n'aurais jamais trouvé ça toute seule !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Afficher du XML dans une table HTML avec fonction récursive (ou pas)
    Par iviewclear dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 19/04/2010, 17h04
  2. Réponses: 12
    Dernier message: 02/04/2007, 16h17
  3. Réponses: 2
    Dernier message: 02/04/2007, 13h21
  4. [FLASH 8] Problème de sélection dans une liste
    Par jpboogie dans le forum Flash
    Réponses: 3
    Dernier message: 29/09/2006, 14h12
  5. [CSS] Problème d'espaces dans une liste
    Par sylsau dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 03/08/2006, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo