web-dev-qa-db-fra.com

Comment ajouter des valeurs à un ensemble dans une carte?

J'ai cette carte Map<String, Set<Integer>> myMap;, maintenant je dois interagir avec elle, comment puis-je le faire?


par exemple:

Les clés sont: "Apple", "orange", "raisin", etc.
Chaque ensemble contiendra des nombres aléatoires: 1-9

J'ai besoin de créer une carte (HashMap ou TreeMap) qui contient des chaînes pour les clés et des ensembles pour les valeurs. Je dois retourner l'ensemble donné une clé. Je dois aussi pouvoir remplir chaque ensemble avec plusieurs numéros basés sur une clé. Vous ne savez pas comment aborder ce problème. Des pensées?

7
user2242203

Pas difficile si je comprends bien.

Map<String, Set<Integer>> reqdMap = new HashMap<String, Set<Integer>>();

//Form the set corresponding to Apple.
Set<Integer> appleSet = new HashSet<Integer>();
appleSet.add(1);
...


reqdMap.put("Apple", appleSet);

//To Retrieve
appleSet = reqdMap.get("Apple");
11
prashant

Il convient de garder à l'esprit que la valeur sera initialement nulle et que, dès la première utilisation d'une clé, vous devrez l'initialiser:

Map<String,Set<Integer>> map;  

Pour ajouter un numéro à la clé, vous devez procéder comme suit:

String key = "Apple"; // for example 

Set<Integer> set = map.get(key); 
if (set == null) {
    set = new HashSet<Integer>();
    map.put(key, set);
}
set.add(5);

Malheureusement, partout où vous interagissez avec l'ensemble, vous devez effectuer un contrôle nul. Par exemple, si vous voulez vérifier si une certaine clé est associée à un certain nombre, vous ne pouvez pas le faire en toute sécurité:

if (map.get(key).contains(number))  // not safe

parce que l'appel à get() peut renvoyer null (s'il n'y a pas d'entrée pour la clé) et que vous obtiendrez une NullPointerException.

Il existe un moyen de rendre votre carte très pratique à utiliser en internalisant le contrôle null à l'intérieur de la carte, de sorte qu'un appel à get() renvoie toujours un ensemble non nul; créez une classe anonyme qui remplace get() en conséquence:

Map<String,Set<Integer>> map = new HashMap<String,Set<Integer>> () {
    @Override
    public Set<Integer> get(Object key) {
        Set<Integer> set = super.get(key); 
        if (set == null) {
            set = new HashSet<Integer>();
            put(key, set);
        }
        return set;
    }
}

Avec cela en place, votre code principal devient beaucoup plus simple et clair. Ajouter:

map.get(key).add(number);

Vérifier:

if (map.get(key).contains(number)) // now safe

Le code de vérification nul n'est plus nécessaire.

——

Mise à jour Java 8:

Pour traiter le problème de la saisie de valeur nulle lors de l'ajout à l'ensemble:

map.computeIfAbsent( key, k -> new HashSet<>() ).add(number);

et pour la vérification null safe:

if ( map.getOrDefault(key, Collections.emptySet() ).contains(number))
8
Bohemian

Pourquoi ne pas regarder ceci:

https://github.com/google/guava/wiki/NewCollectionTypesExplained#multimap

MultiMap vous permet de stocker plusieurs valeurs pour une clé donnée de manière très efficace.

Dans votre cas, le grand avantage est que vous n'êtes pas obligé de récupérer une valeur (Set) à partir d'une clé donnée afin de lui ajouter des valeurs. 

En effet, il vous suffit d’ajouter la valeur à la clé comme si vous traitiez avec "monovalue" et elle sera automatiquement ajoutée à la set en arrière-plan.

4
Mik378
Map<String, Set<Integer>> mapOfSets = new HashMap<String, Set<Integer>>();
Set<Integer> numberSet = new HashSet<Integer>();

//put a set into the map
mapOfSets.put("key", numberSet);
//get a set out of the map
Set<Integer> set = mapOfSets.get("key");
0
Jainathan Leung

Si vous souhaitez ajouter plusieurs nombres à un ensemble avec une seule méthode, essayez ceci:

Map<String, Set<Integer>> map; // Definition


public void addValues(String key, Integer... values) {
    map.get(key).addAll(values);
}

Ainsi, lorsque vous devez ajouter plusieurs numéros pour une touche, vous pouvez effectuer un appel comme ceci:

addValues("Apple", 1, 2, 4, 6, 8);

Une ligne au lieu de 5.

0
Rob Watts

ceci est juste un exemple classe complète. il suffit de l'exécuter et d'y travailler pour en savoir plus sur ce problème

public class Tester5 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //"Apple", "orange", "grape", etc. Each set will contain random numbers: 1, 2, 3, 4, 5, 6, 7, 8, 9

        Random ran = new Random();

        Map<String, Set<Integer>> map= new HashMap<String, Set<Integer>>();
        String keys[]= {"Apple", "orange", "grape"};
        for(String key : keys) {
            Set<Integer> integers= new HashSet<Integer>();
            for(int i = 0; i < 10; i++) {
                 integers.add(ran.nextInt(9)+1);
            }
            map.put(key, integers);
        }
        System.out.println(map.toString());

    }

}
0
Festus Tamakloe
Map<String,Set<Integer>> map;  
Set<Integer> set = map.get("Apple");  

J'omets la population réelle de map puisque le PO est comment get l'ensemble c'est-à-dire la valeur

0
Cratylus