232 votes

HashMap avec plusieurs valeurs sous la même clé

Est-il possible pour nous d'implémenter un HashMap avec une clé et deux valeurs. Tout comme HashMap ?

Veuillez m'aider, en m'indiquant (s'il n'y a pas d'autre moyen) une autre façon d'implémenter le stockage de trois valeurs avec une comme clé ?

2 votes

0 votes

Merci les amis...mais j'ai quelques limitations dans l'utilisation de MultiHashMap

0 votes

296voto

Paul Ruane Points 12840

Tu pourrais :

  1. Utilisez une carte dont la valeur est une liste. Map<KeyType, List<ValueType>> .
  2. Créez une nouvelle classe de wrapper et placez des instances de ce wrapper dans la carte. Map<KeyType, WrapperType> .
  3. Utiliser une classe de type tuple (évite de créer de nombreux wrappers). Map<KeyType, Tuple<Value1Type, Value2Type>> .
  4. Utilisez plusieurs cartes côte à côte.

Exemples

1. Carte avec une liste comme valeur

// create our map
Map<String, List<Person>> peopleByForename = new HashMap<>();    

// populate it
List<Person> people = new ArrayList<>();
people.add(new Person("Bob Smith"));
people.add(new Person("Bob Jones"));
peopleByForename.put("Bob", people);

// read from it
List<Person> bobs = peopleByForename["Bob"];
Person bob1 = bobs[0];
Person bob2 = bobs[1];

L'inconvénient de cette approche est que la liste n'est pas liée à deux valeurs exactement.

2. Utilisation de la classe enveloppe

// define our wrapper
class Wrapper {
    public Wrapper(Person person1, Person person2) {
       this.person1 = person1;
       this.person2 = person2;
    }

    public Person getPerson1 { return this.person1; }
    public Person getPerson2 { return this.person2; }

    private Person person1;
    private Person person2;
}

// create our map
Map<String, Wrapper> peopleByForename = new HashMap<>();

// populate it
Wrapper people = new Wrapper();
peopleByForename.put("Bob", new Wrapper(new Person("Bob Smith"),
                                        new Person("Bob Jones"));

// read from it
Wrapper bobs = peopleByForename.get("Bob");
Person bob1 = bobs.getPerson1;
Person bob2 = bobs.getPerson2;

L'inconvénient de cette approche est que vous devez écrire beaucoup de code passe-partout pour toutes ces classes de conteneurs très simples.

3. Utilisation d'un tuple

// you'll have to write or download a Tuple class in Java, (.NET ships with one)

// create our map
Map<String, Tuple2<Person, Person> peopleByForename = new HashMap<>();

// populate it
peopleByForename.put("Bob", new Tuple2(new Person("Bob Smith",
                                       new Person("Bob Jones"));

// read from it
Tuple<Person, Person> bobs = peopleByForename["Bob"];
Person bob1 = bobs.Item1;
Person bob2 = bobs.Item2;

C'est la meilleure solution à mon avis.

4. Cartes multiples

// create our maps
Map<String, Person> firstPersonByForename = new HashMap<>();
Map<String, Person> secondPersonByForename = new HashMap<>();

// populate them
firstPersonByForename.put("Bob", new Person("Bob Smith"));
secondPersonByForename.put("Bob", new Person("Bob Jones"));

// read from them
Person bob1 = firstPersonByForename["Bob"];
Person bob2 = secondPersonByForename["Bob"];

L'inconvénient de cette solution est qu'il n'est pas évident que les deux cartes sont liées, une erreur de programmation pourrait faire en sorte que les deux cartes ne soient pas synchronisées.

0 votes

Bonjour Paul...pouvez-vous être un peu plus clair...en donnant un exemple... ?

0 votes

@vidhya : lequel en particulier correspond à votre problème ? Vos objets multiples sont-ils du même type ou différents ?

0 votes

Un exemple serait génial en fait.

63voto

Jon Skeet Points 692016

Non, pas seulement en tant que HashMap . Vous auriez essentiellement besoin d'un HashMap d'une clé à une collection de valeurs.

Si vous êtes heureux d'utiliser des bibliothèques externes, Goyave a exactement ce concept dans Multimap avec des mises en œuvre telles que ArrayListMultimap , HashMultimap , LinkedHashMultimap etc.

Multimap<String, Integer> nameToNumbers = HashMultimap.create();

System.out.println(nameToNumbers.put("Ann", 5)); // true
System.out.println(nameToNumbers.put("Ann", 5)); // false
nameToNumbers.put("Ann", 6);
nameToNumbers.put("Sam", 7);

System.out.println(nameToNumbers.size()); // 3
System.out.println(nameToNumbers.keySet().size()); // 2

0 votes

@Jon, pourriez-vous fournir un exemple de travail en Java pour la question ci-dessus posée par l'OP.

2 votes

@Deepak : Cherchez guava multimap examples et vous trouverez des exemples de code.

0 votes

@Jon, désolé de vous déranger encore et encore, je ne veux pas utiliser Gauava, comment puis-je le faire en Core Java ? nous n'utilisons pas Gauava et nous ne sommes pas censés utiliser MultiMap.

25voto

Matt Points 602

Un autre bon choix est d'utiliser MultiValuedMap d'Apache Commons. Jetez un coup d'œil à la Toutes les classes d'implémentation connues en haut de la page pour les implémentations spécialisées.

Exemple :

HashMap<K, ArrayList<String>> map = new HashMap<K, ArrayList<String>>()

pourrait être remplacé par

MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();

Donc,

map.put(key, "A");
map.put(key, "B");
map.put(key, "C");

Collection<String> coll = map.get(key);

entraînerait la collecte coll contenant "A", "B", et "C".

14voto

Bozho Points 273663

Jetez un coup d'œil à Multimap à partir des bibliothèques guava et de sa mise en œuvre - HashMultimap

Une collection similaire à une Map, mais qui peut associer plusieurs valeurs à une seule clé. Si vous appelez put(K, V) deux fois, avec la même clé mais des valeurs différentes, la multimap contient les mappings de la clé vers les deux valeurs.

2voto

Nicolas Points 11558

Oui et non. La solution est de construire une classe Wrapper pour vos valeurs qui contient les 2 (3, ou plus) valeurs qui correspondent à votre clé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X