web-dev-qa-db-fra.com

Un tableau Java peut-il être utilisé comme clé HashMap?

Si la clé d'une table de hachage est un tableau de chaînes:

HashMap<String[], String> pathMap;

Pouvez-vous accéder à la carte en utilisant un tableau de chaînes nouvellement créé ou doit-il s'agir du même objet String []?

pathMap = new HashMap<>(new String[] { "korey", "docs" }, "/home/korey/docs");
String path = pathMap.get(new String[] { "korey", "docs" });
21
Korey Hinton

Ce devra être le même objet. HashMap compare les clés utilisant equals() et deux tableaux en Java ne sont égaux que s'ils sont le même objet.

Si vous souhaitez l'égalité des valeurs, écrivez votre propre classe de conteneur qui enveloppe un String[] et fournit la sémantique appropriée pour equals() et hashCode(). Dans ce cas, il serait préférable de rendre le conteneur immuable, car la modification du code de hachage d'un objet crée des dégâts considérables avec les classes de conteneur basées sur le hachage.

MODIFIER

Comme d'autres l'ont fait remarquer, List<String> possède la sémantique que vous semblez vouloir pour un objet conteneur. Donc, vous pourriez faire quelque chose comme ça:

HashMap<List<String>, String> pathMap;

pathMap.put(
    // unmodifiable so key cannot change hash code
    Collections.unmodifiableList(Arrays.asList("korey", "docs")),
    "/home/korey/docs"
);

// later:
String dir = pathMap.get(Arrays.asList("korey", "docs"));
33
Ted Hopp

Non, mais vous pouvez utiliser List<String> qui fonctionnera comme prévu! 

6
Tom Carchrae

Les tableaux en Java utilisent la hashCode() de Object et ne la remplacent pas (la même chose avec equals() et toString()). Donc non, vous ne peux pas ne devrait pas utiliser les tableaux comme une clé de hachage.

1
Eng.Fouad

Ted Hopp a raison, il faudra que ce soit le même objet 

pour information voir cet exemple

public static void main(String[] args) {
        HashMap<String[], String> pathMap;
        pathMap = new HashMap<String[], String>();
        String[] data = new String[] { "korey", "docs" };
        pathMap.put(data, "/home/korey/docs");
        String path = pathMap.get(data);
        System.out.println(path);
    }
}

Lorsque vous courez dessus, il imprimera "docs".

1
Makky

Vous ne pouvez pas utiliser une Array Java simple comme clé dans une HashMap. (Eh bien, vous pouvez, mais cela ne fonctionnera pas comme prévu.)

Cependant, vous pouvez écrire une classe wrapper comportant une référence au tableau et remplaçant également hashCode() et equals().

1
pvorb

Dans la plupart des cas, lorsque les chaînes de votre tableau ne sont pas pathologiques et n'incluent pas de virgules suivies d'un espace, vous pouvez utiliser Arrays.toString() comme clé unique. c'est-à-dire que votre Map serait un Map<String, T>. Et le get/put pour un tableau myKeys[] serait

T t = myMap.get(Arrays.toString(myKeys));

myMap.put(Arrays.toString(myKeys), myT);

Évidemment, vous pouvez insérer du code wrapper si vous le souhaitez.

Un bel effet secondaire est que votre clé est maintenant immuable. Bien sûr, si vous changez votre tableau myKeys et essayez ensuite une get(), vous ne le trouverez pas.

Le hachage des chaînes est hautement optimisé. Donc, mon suppose est que cette solution, bien qu'elle semble un peu lente et volumineuse, sera à la fois plus rapide et plus efficace en mémoire (moins d'allocations d'objets) que la solution @Ted Hopp utilisant une liste immuable. Il suffit de se demander si Arrays.toString() est unique pour vos clés. Sinon, ou en cas de doute, (par exemple, la chaîne [] provient d'une entrée utilisateur), utilisez la liste.

0
user949300