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 :

Je n'arrive pas à utiliser Vector.indexOf()


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Décembre 2010
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2010
    Messages : 12
    Par défaut Je n'arrive pas à utiliser Vector.indexOf()
    Bonjour,

    j'ai un soucis avec un Vector<char[]>. Je ne parviens à récupérer l'index d'aucun élément.

    J'ai donc un Vector déclaré comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static Vector<char[]> hashTab = null;
    Je l'initialise pas la suite avec des char[] de 2 caractères (AB,QW,ER, etc.) à partir d'un String[] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    String[] str= {"BG", "WJ", "XB", "QW", "ZG"};
    for(int i=0; i<str.length ; i++)
    {
        hashTab.add(str[i].toCharArray());
    }
    Si je fais un j'obtiens bien QW. Mais si j'essaye de récupérer l'index de QW j'obtiens toujours -1.

    J'ai essayé comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char [] currentWord = new char[2];
    currentWord[0] = 'Q';
    currentWord[1] = 'W';
    int index = hashTab.indexOf(currentWord);
    ou encore comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int index = hashTab.indexOf("QW");
    mais apparement c'est pas ça... une idée ?

    merci d'avance !

    Popollux.

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    bonjour.
    Je pense que la raison de ton problème est la suivante:
    indexOf utilise une comparaison par la méthode "equals" des valeurs. Or un tableau de caractères et une chaine de caractère de type String ne sont pas égaux à la comparaison par equals. Donc il ne retrouve pas l'élément recherché puisque tu transformes ta chaine en tableau de caractères. Est-ce vraiement nécessaire pour tes traitements? Tu pourrais très bien insérer les objets String tels quels (ils ont d'ailleurs dans leur interface des méthodes pour récupérer les caractères par index) et dans ce cas "QW" serait retrouvé par la méthode indexOf.

    PS: ne serais tu pas plus familier avec C ou C++ par hasard?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    String[] str= {"BG", "WJ", "XB", "QW", "ZG"};
    for(int i=0; i<str.length ; i++)
    {
        hashTab.add(str[i]);
    }
    int indexOfQw=hashTab.indexOf("QW");

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Oui, c'est une limitation connue.

    Les méthodes comme contains(), indexOf(), remove(), ou tous les trucs qui cherchent un objet dans une collection, ont un point commun :
    elles se basent sur la méthode public boolean equals(Object).
    En gros, quand tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int index = vector.contains(monObjet);
    Ce qui va se passer, c'est une boucle sur tout les éléments de vector, et pour chaque élément e il va appeler :

    Si c'est true, la boucle considère que l'objet a été trouvé, si c'est false il passe au suivant.

    C'est clair ? Bien.

    C'est pour ça que quand on crée de nouvelles classes, dont les instances vont être stockées dans des collections et qu'on doit pouvoir les chercher à l'intérieur, il faut redéfinir la méthode public boolean equals(Object), qui dira donc si l'objet en cours est égal à l'objet passé en paramètre.
    Si on ne le fait pas, la classe héritera de la méthode equals() de Object, et a priori c'est pas ce qu'on veut.

    Bien. Et alors ?

    Et alors en Java, les tableaux n'implémentent pas equals(). Par conséquent, deux tableaux qui contiennent la même chose ne sont pas considérés égaux. Une instance de tableau n'est égale qu'à elle-même.

    Donc c'est pas possible avec des tableaux.

    => Ce que tu peux faire, c'est utiliser un Vector à la place de tableaux : ce qui te donne un Vector<Vector<Character>>

    => Et en fait, vu que les Vector ce n'est utile que si tu as besoin d'accès synchronisé, ce qui n'est pas le cas je suppose, tu ferais mieux d'utiliser des List : List<List<Character>>.

    => Par ailleurs, List<Character> ou char[], ce n'est utile que si les caractères doivent pouvoir être changés. Si ce n'est pas le cas, il faut bien sûr utiliser String. C'est juste plus simple.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre habitué
    Inscrit en
    Décembre 2010
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2010
    Messages : 12
    Par défaut
    @therwald : oui, je suis plutôt familier avec le C/C++.
    @thelvin : merci pour ces éclaircissements. Je suppose que dans mon cas la méthode equals() doit comparer les adresses mémoire de chaque instance, donc comme tu dis c'est forcément faux tout le temps, sauf pour soi-même.

    Je pense que je vais simplement passer de Vector à List et redéfinir la méthode equals() pour les char[].

    J'utilise des char[] pour des raisons de sécurité, puisqu'apparemment les String sont conservés en mémoire, même après déréférencement, pour des raisons d'optimisation.

    Merci !

  5. #5
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    À noter que tu peux aussi le faire "à la mano" avec la méthode Arrays.equals().

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Je ne suis pas certain de comprendre tes considérations de sécurité?
    Quoi qu'il en soi, tu ne peux pas redéfinir equals pour char[], car cette classe est une classe spéciale créée par l'environnement java.
    A moins que tu n'utilise une méthode de recherche externe pour chercher dans ta collection, mais ce serait un peu réinventer la roue...
    Il existe des classes de chaines de caractères mutable (StringBuilder, StringBuffer) qui ne partagent pas leurs buffers, puisqu'ils sont susceptibles de modifications, donc je suppose qu'ils sont supprimés lors de la garbage collection.

  7. #7
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Il peut toujours coder une classe de Wrap. Ou, comme je le disais, coder à la main le indexOf, en évitant la double boucle avec l'utilisation de Arrays.equals().

Discussions similaires

  1. J'arrive pas à utiliser JProgressBar !
    Par med_anis_dk dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 04/06/2007, 07h22
  2. Réponses: 2
    Dernier message: 12/04/2007, 08h42
  3. Je n'arrive pas à utiliser le Double buffering
    Par Yann39 dans le forum AWT/Swing
    Réponses: 43
    Dernier message: 21/01/2007, 22h14
  4. J'arrive pas à utiliser l'authentification par clé sur ma debian
    Par biglittlekiss dans le forum Sécurité
    Réponses: 2
    Dernier message: 11/12/2006, 13h15
  5. Réponses: 4
    Dernier message: 22/05/2006, 11h46

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