web-dev-qa-db-fra.com

Convertir l'ensemble <Map.Entry <K, V >> en HashMap <K, V>

À un moment donné dans mon code, j'ai créé un Set<Map.Entry<K, V>> à partir d'une carte. Maintenant, je veux recréer le même formulaire, donc je veux reconvertir le HashSet<Map.Entry<K, V>> en un HashMap<K, V>. Java a-t-il un appel natif pour ce faire ou dois-je parcourir les éléments définis et construire la carte manuellement?

21
Joeblackdev

Il n'y a pas d'API incorporée dans Java pour la conversion directe entre HashSet et HashMap, vous devez effectuer une itération sur l'ensemble et utiliser Entry pour remplir la mappe.

une approche:

Map<Integer, String> map = new HashMap<Integer, String>();
    //fill in map
    Set<Entry<Integer, String>> set = map.entrySet();

    Map<Integer, String> mapFromSet = new HashMap<Integer, String>();
    for(Entry<Integer, String> entry : set)
    {
        mapFromSet.put(entry.getKey(), entry.getValue());
    }

Quel que soit le but ici, si vous apportez des modifications à Set qui seront également répercutées dans Map, telles que définies par Map.entrySet sont sauvegardées par Map. Voir javadoc ci-dessous:

Définir <Entrée <Integer, String >> Java.util.Map.entrySet ()

Renvoie une vue d'ensemble des mappages contenus dans cette carte. L'ensemble est sur la carte, les modifications apportées à la carte sont reflétées dans le jeu, et vice versa. Si la carte est modifiée alors qu’une itération sur l’ensemble est définie en cours (sauf via l'opération de suppression propre de l'itérateur, ou via l'opération setValue sur une entrée de carte renvoyée par l'itérateur .__), les résultats de l'itération ne sont pas définis. L'ensemble prend en charge suppression d'élément, qui supprime le mappage correspondant de la carte, via le Iterator.remove, Set.remove, removeAll, rétentionAll et effacer opérations. Il ne prend pas en charge les opérations add ou addAll.

19
harsh

Solution Java-8 simplifiée impliquant Collectors.toMap:

Map<Integer, String> mapFromSet = set.stream()
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

Une IllegalStateException sera levée si une clé dupliquée est rencontrée.

35
Tagir Valeev

À partir de Guava 19, vous pouvez utiliser ImmutableMap.copyOf(Iterable<Map.Entry<K,V>>)

5
Neil

Solution Java 8 assez courte. Peut faire face à des clés en double.

    Map<Integer, String> map = new HashMap<>();
    //fill in map
    Set<Map.Entry<Integer, String>> set = map.entrySet();
    Map<Integer, String> mapFromSet = set.stream().collect(Collectors.toMap(Entry::getKey,
      Entry::getValue,
      (a,b)->b));

Edit: merci à shmosel qui mérite plus de crédit que moi pour cela

5
mikeyreilly

Ce sont des utilitaires toMap dans les bibliothèques communes, mais malheureusement aucun d’entre eux ne supporte Set directement, vous devez donc commencer par Set#toArray(). (J'ai laissé de côté Goyave pour réponse de Neil qui est sans doute le meilleur)

Commons Lang's ArrayUtils.toMap

Map<Object, Object> map = ArrayUtils.toMap(entrySet.toArray());

// to recover the type...
@SuppressWarnings("unchecked")
Map<K, V> typedMap = (Map<K, V>)(Map<?, ?>)map;

Commons Collections ' MapUtils.putAll

Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray());

Java 9's Map.ofEntries

 // convert to array and recover the type...
 @SuppressWarnings("unchecked")
 Map.Entry<K, V>[] array = entrySet.toArray((Map.Entry<K, V>[])new Map.Entry<?, ?>[entrySet.size()]);

 Map<K, V> map = Map.ofEntries(array);

 // You need to copy again if you want mutable one
 Map<K, V> hashmap = new HashMap<>(map);
2
snipsnipsnip

En Java 8 avec le bon combinateur

Map<Integer, String> map = new HashMap<>();
//fill in map
Set<Map.Entry<Integer, String>> set = map.entrySet();

Map<Integer, String> mapFromSet =set.stream().collect(HashMap::new,(t, u) -> t.put(u.getKey(), u.getValue()), 
(Map mapToReturn, Map otherMap) ->
    {
        otherMap.entrySet().forEach((Map.Entry entry) -> {
            mapToReturn.put(entry.getKey(),entry.getValue());
        });
        return mapToReturn;}););
0
Joe