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

Collection et Stream Java Discussion :

[HashMap] valeur associée à une clé changeante


Sujet :

Collection et Stream Java

  1. #1
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Septembre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Septembre 2004
    Messages : 114
    Par défaut [HashMap] valeur associée à une clé changeante
    Bonjour,

    Je sais que vu le titre cela n'est pas très explicite, je vais essayer de vous détailler mon problème.
    Tout cela correspond à un programme qui doit donner le plus court chemin entre deux sommets d'un graphe valué .

    Ma structure est ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private HashMap<Sommet,TreeSet<Arc>> graphe;
    J'ai donc une classe Sommet qui contient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    private String nom; 
    	private int plusCourt; // valuation associé au sommet
    Et une classe Arc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    private Sommet arrivee;
    	private int poids;
    J'ai crée tous les sommets et tous les arcs. J'ai entré dans la hashmap pour chaque sommet les arcs associés.
    Tout cela fonctionne à merveille !

    Maintenant je souhaite modifier l'attribut plusCourt pour tous les sommets contenus dans le hashmap.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for(Sommet s: graphe.keySet()){
     
    			if(s.getNom()==depart)
    			{
    				sommetDepart = s;
    				s.setPlusCourt(0);
     
    			}
    			else
    			{
    				s.setPlusCourt(3000);	
    			}
    		}
    Et en fait après avoir executé ce code, lorsque je parcours toutes les clés pour afficher la valeur, je n'ai que des null ?!? Logiquement si je modifie une clé elle devrait garder sa valeur associé dans le hashmap ?

    Merci de m'éclairer la dessus.

    Louis

  2. #2
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    o_O

    Pas de comparaison == sur des chaînes

    Ton "null" tu l'as où précisément?

  3. #3
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Septembre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Septembre 2004
    Messages : 114
    Par défaut
    En fait j'ai mis ce bout de code avant et après le traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    TreeSet<Arc> tmp;
    		for(Sommet s:  graphe.keySet()){
     
     
    			tmp =graphe.get(s);	
    					System.out.println(tmp);
    		}
    Il s'avere que avant tout est correct, et après j'ai un affichage avec des null !

  4. #4
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,


    Les objets utilisé en clef dans les Map devraient être immuable : si leurs valeurs changent il y a de forte chance qu'il soit impossible de les retrouver...

    C'est d'ailleurs indiqué dans la javadoc : http://javasearch.developpez.com/j2s.../util/Map.html
    Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.
    C'est comme si tu change de clef : tu ne peux plus ouvrir ta porte

    a++

  5. #5
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Septembre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Septembre 2004
    Messages : 114
    Par défaut
    Merci pour ta réponse,

    j'ai donc décider de modifier mon code pour supprimer l'entrée associée à l'ancienne clé et ajouter la nouvelle de cette manière

    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
    for(Sommet s: lesKey){
    			Sommet tmpSomm = s;
    			TreeSet<Arc> tmpTree = graphe.get(s);
     
    			if(s.getNom().equals(depart))
    			{
    				sommetDepart = s;
    				s.setPlusCourt(0);
    				graphe.remove(tmpSomm);
    				graphe.put(s, tmpTree);
     
    			}
    			else
    			{
    				s.setPlusCourt(3000);
    				graphe.remove(tmpSomm);
    				graphe.put(s, tmpTree);
    			}
    		}
    Mais là j'ai une belle erreur :
    Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
    at java.util.HashMap$KeyIterator.next(Unknown Source)
    at Graphe.calcul(Graphe.java:74)
    at Application.main(Application.java:82)

    La je dois avouer que c'est la première fois que je la rencontre et je suis perdu ! Est-ce la bonne méthode à faire ?

    Merci encore pour votre aide

  6. #6
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Lorsque tu parcours une collections avec un itérateur (ce qui est utilisé lorsque tu utilises la boucle for étendu), tu ne dois pas modifier la collection en même temps (sauf si tu passe par les méthodes de l'itérateur).

    Donc utilise une Map temporaire

    a++

  7. #7
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Septembre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Septembre 2004
    Messages : 114
    Par défaut
    D'accord, mais meme en rajoutant cela ca ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    HashMap<Sommet,TreeSet<Arc>> mapTmp = graphe;
    Set<Sommet> lesKey = mapTmp.keySet();
    Cela vient du fait que ca référence les memes objets en mémoire ?
    Il faudrait que j'en crée de nouveau ?

    Merci d'avance pour ton aide précieuse

  8. #8
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par allserv
    Cela vient du fait que ca référence les memes objets en mémoire ?
    Il faudrait que j'en crée de nouveau ?
    Oui et oui : tu ne crée pas une Map temporaire mais une seconde référence sur la même Map...

    a++

  9. #9
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Septembre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Septembre 2004
    Messages : 114
    Par défaut
    Désolé c'est encore moi, en, fait je viens de me rendre compte que après je remodifie encore les sommets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    TreeSet<Arc> tmp=graphe.get(sommetDepart);	
     
    		for(Arc a: tmp){
     
    			if(sommetDepart.getPlusCourt()+a.getPoids()<a.getArrivee().getPlusCourt()){					
    				a.getArrivee().setPlusCourt(sommetDepart.getPlusCourt()+a.getPoids());
    			}
    		}
    EN effet dans les arc cela contient un sommet qui est l'attribut arriive et je modifie l'attribut plusCourt.

    Le mieux dans ce cas ne serait pas que je fasse un tableau avec les noms des sommets et leur valeur plusCourt ?

    Comment faire un tableau avec une colonne de String et en valeur des int ?

    Merci encore

  10. #10
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Septembre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Septembre 2004
    Messages : 114
    Par défaut
    C'est bon mon problème est resolu, il suffisait d'adapter le bon hashcode sur le nom et non sur les deux attributs comme ca ca ne le prenait pas come une nouvelle clé

    Un autre petit problème tout bete mais dont je ne trouve pas la solution

    Dans mon TreeSet d'arc, lorsque j'ai deux Arc différents mais avec le meme poids, le dernier arc n'est pas ajouté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Arc AB = new Arc(B,1);
    Arc AD = new Arc(D,2);
    Arc AC = new Arc(C,1);
     
    monGraphe.ajoutArc(A,AB);
    monGraphe.ajoutArc(A,AD);
    monGraphe.ajoutArc(A,AC);
    Dans cet exemple je n'ai pas l'arc AC par exemple !

    Pourtant j'ai defini le hashcode sur le sommet d'arrivée qui diffère donc devrait pas y avoir de problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     public int hashCode() {
    	        return arrivee.hashCode();
    	 }
     
    	 public boolean equals(Arc monArc){
    		 return (monArc.arrivee.equals(this.arrivee) && monArc.getPoids()==this.poids);
    	 }
    Et le hashcode du sommet est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     public int hashCode() {
    	       return nom.hashCode();
    	    }
     
    	 public boolean equals(Sommet otre){
    		 return otre.getNom().equals(this.nom);
    	 }
    Comment faire pour résoudre ce dernier problème ?

    Je te remercie encore pour tes reponses

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/05/2015, 19h00
  2. Réponses: 20
    Dernier message: 25/09/2013, 12h24
  3. [XL-2007] Afficher toutes les valeurs associées à une autre valeur
    Par lecter85 dans le forum Excel
    Réponses: 2
    Dernier message: 19/12/2012, 18h23
  4. [JSTL] [Map] comment récupérer la valeur associée à une clé
    Par jamal_id dans le forum Taglibs
    Réponses: 8
    Dernier message: 02/08/2007, 15h51
  5. [RegEx] Gérer deux possibilités et leur associer une valeur 0/1
    Par speed_man002 dans le forum Langage
    Réponses: 3
    Dernier message: 21/09/2005, 18h32

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