Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[Map] Comment accéder à une valeur avec un tableau en clef ?

5 réponses
Avatar
kwen
Bonjour,

J'ai un petit probl=E8me, je souhate acc=E9der =E0 une valeur de ma map
mais je n'y arrive pas avec un tableau en tant que clef, cela est il
possible ?

ma_map.put(new String[] {"1", "bla"}, "une valeur");
ma_map.get(new String[] {"1", "bla"}); =3D> cela me renvoie null :(

Merci de votre aide

5 réponses

Avatar
Wamli
Tout simplement parce que tu créées deux tableaux qui sont égaux quant à
leur contenu mais pas quant à leur référence.

Tu peux essayer le code suivant :

{ String[] tab1 = {"1", "bla"};
String[] tab2 = {"1", "bla"};

System.out.println(tab1);
System.out.println(tab2);
}

tu verras que même si le contenu des tableaux est égal, ils correspondent
bien à deux références distinctes (le code en 4543abf placé après l' @ ).

En d'autres termes, on peut dire quand tu fais un get(Object o1) avec une
map, Java va (c'est un peu plus compliqué en fait mais dans l'idée c'est ca)
prendre un à un les clés et faire le test

clé_no_n.equals(o1)

Si le test est positif, alors il renvoie la valeur associée à la clé no_n

Cela dépend donc du comportement de la méthode "equals" qui peut être
différente dans chaque objet. Si cette méthode n'est pas définie
spécifiquement, java teste sur la "position mémoire" (en fait la référence)
de l'objet. Donc deux objets parfaitement similaires mais qui ont été
déclarés séparément ne seront pas forcément égaux, donc

((new Object()).equals(new Object()) = false;


Par contre, dans la classe Integer par exemple, la méthode equals doit
contenir à peu près ça :

class Integer {

int value = ...;

.....

public boolean equals(Integer i) {
return (i.intValue() == value);
}

}

et donc

((new Integer(3)).equals(new Integer(3)) = true;

Mais pour les tableaux, cela prendrait trop de temps de mettre au point une
méthode "equals" qui compare un à un tout les termes contenus, surtout si
ceux-ci sont à leur tour des tableaux ou d'autres objets. Java s'en tient
donc à la référence



"kwen" wrote in message
news:
Bonjour,

J'ai un petit problème, je souhate accéder à une valeur de ma map
mais je n'y arrive pas avec un tableau en tant que clef, cela est il
possible ?

ma_map.put(new String[] {"1", "bla"}, "une valeur");
ma_map.get(new String[] {"1", "bla"}); => cela me renvoie null :(

Merci de votre aide
Avatar
Wamli
La solution serait de stocker ta clé quelque part, ou alors de prendre une
clé directement comparable (voire réponse précédente).

Tu peux par exemple déclarer une static String[] foo = {"1", "bla"};

et l'utiliser ensuite comme clé



"kwen" wrote in message
news:
Bonjour,

J'ai un petit problème, je souhate accéder à une valeur de ma map
mais je n'y arrive pas avec un tableau en tant que clef, cela est il
possible ?

ma_map.put(new String[] {"1", "bla"}, "une valeur");
ma_map.get(new String[] {"1", "bla"}); => cela me renvoie null :(

Merci de votre aide
Avatar
alexandre cartapanis
kwen wrote:
Bonjour,

J'ai un petit problème, je souhate accéder à une valeur de ma map
mais je n'y arrive pas avec un tableau en tant que clef, cela est il
possible ?

ma_map.put(new String[] {"1", "bla"}, "une valeur");
ma_map.get(new String[] {"1", "bla"}); => cela me renvoie null :(

Merci de votre aide

je pense que mettre des tableaux comme clé ce n'est pas une bonne idé e

mais bon...

Deux solutions s'offre a toi:

Soit tenter de manipuler les tableaux en utilisant la classe
java.lang.reflect.Array. Ca risque d'etre long et compliqué.

Soit convertir les tableaux en liste, mais la il faut faire tres tres
attention. Lorsque tu utilises une map, les objets clés doivent
respecter un certain nombre de contraintes, en ce qui concerne la
methode hashCode, equals, ... Ca m'est difficile de t'en dire plus
(parce je n'en sais pas plus!!) mais regarde sur java.sun.com, il y a
certainement la reponse a ce probleme.

Mon conseil neanmoins: evite les clés a base de tableaux. Tu peux par
exemple convertir tes tableaux en chaine de caractere (avec
java.util.Arrays.toString([])). Ou bien ecrire ta propre routine
permettant de convertir un tableau en String et inversement.

Avatar
Simon OUALID
Wamli wrote:
La solution serait de stocker ta clé quelque part, ou alors de prendre une
clé directement comparable (voire réponse précédente).

Tu peux par exemple déclarer une static String[] foo = {"1", "bla"};

et l'utiliser ensuite comme clé



Oui, puisque dans ton cas c'est les adresses mémoires qui seront
comparées par equals(). En utilisant des propriétés statiques, tu es sur
de tapper sur la même clef.

L'autre méthode (plus élégante à mon goût) est de créer ton propre
objet, qui implémentera hashCode et equals (voir doc de HashMap et Object).

Avatar
David Molinier
kwen wrote:

Bonjour,

J'ai un petit problème, je souhate accéder à une valeur de ma map
mais je n'y arrive pas avec un tableau en tant que clef, cela est il
possible ?

ma_map.put(new String[] {"1", "bla"}, "une valeur");
ma_map.get(new String[] {"1", "bla"}); => cela me renvoie null :(

Merci de votre aide

je pense que mettre des tableaux comme clé ce n'est pas une bonne idée

mais bon...

Deux solutions s'offre a toi:
[...]

Une 3ème solution : la Map de Map. Si tu dois absolument avoir un accès
à double entrée, tu peux construire une structure de données de ce style
(avec ton exemple) :

("1" -> ("bla" -> "une valeur"))

Pour stocker tes valeurs :

m2.put("bla", "une valeur");
m1.put("1", m2);

Pour les récupérer :

((Map)m1.get("1")).get("bla")

Et enfin, pour rendre la syntaxe moins lourde et surtout pour gérer les
problèmes de "java.lang.NullPointerException" lorsque la Map m1 ne
contient pas de valeur pour la clé recherchée, tu encapsule tout ça dans
ta propre classe ou bien...

tu jettes un oeil à l'API commons collection d'Apache
(http://jakarta.apache.org/commons/collections/), et plus précisément
aux classes MultiKey et MultiKeyMap :-)

--
David <*>