268 votes

Comment puis-je combiner deux objets HashMap contenant les mêmes types ?

J'ai deux HashMap définis comme suit :

HashMap<String, Integer> map1 = new HashMap<String, Integer>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();

J'ai aussi un troisième HashMap objet :

HashMap<String, Integer> map3;

Comment puis-je fusionner map1 y map2 ensemble dans map3 ?

374voto

a_horse_with_no_name Points 100769
map3 = new HashMap<>();

map3.putAll(map1);
map3.putAll(map2);

2 votes

Je suis en train de fusionner les cartes dans une boucle for qui utilise une méthode pour retourner une carte et j'ai besoin de la fusionner avec une autre carte et d'appliquer la même méthode à nouveau. Pour cela, j'obtiens une exception de pointeur nul avec la méthode putAll. Cela n'aide pas à utiliser le bloc try/catch. Que dois-je faire ? Je suis en train d'appliquer la condition if, c'est-à-dire que si la taille==o, il ne faut pas appliquer la méthode putAll, sinon il faut l'appliquer et ainsi de suite.....

1 votes

Si vous obtenez un NPE, c'est qu'apparemment vous n'avez pas initialisé correctement l'un de vos objets. Imprimez-vous le suivi de pile dans le bloc de capture ? Ainsi vous savez le problème se pose. Mais si vous ne postez pas le code complet et exact, y compris la trace de la pile, vous devrez le retrouver par vous-même.

118 votes

Notez qu'avec cette solution, si une clé existe dans les deux maps, la valeur dans map2 sera préservée et la valeur dans map1 perdue.

118voto

Jeffrey Bosboom Points 1255

Si vous savez que vous n'avez pas de clés dupliquées, ou si vous voulez que les valeurs dans le fichier map2 pour écraser les valeurs de map1 pour les clés dupliquées, vous pouvez simplement écrire

map3 = new HashMap<>(map1);
map3.putAll(map2);

Si vous avez besoin de plus de contrôle sur la façon dont les valeurs sont combinées, vous pouvez utiliser la commande Map.merge ajouté à Java 8, qui utilise un fichier de données de l'utilisateur. BiFunction pour fusionner les valeurs des clés dupliquées. merge opère sur des clés et des valeurs individuelles, vous devrez donc utiliser une boucle ou une fonction Map.forEach . Ici, nous concaténons les chaînes de caractères pour les clés dupliquées :

map3 = new HashMap<>(map1);
for (Map.Entry<String, String> e : map2.entrySet())
    map3.merge(e.getKey(), e.getValue(), String::concat);
//or instead of the above loop
map2.forEach((k, v) -> map3.merge(k, v, String::concat));

Si vous savez que vous n'avez pas de clés en double et que vous voulez le faire respecter, vous pouvez utiliser une fonction de fusion qui lance un message d'erreur de type AssertionError :

map2.forEach((k, v) ->
    map3.merge(k, v, (v1, v2) ->
        {throw new AssertionError("duplicate values for key: "+k);}));

En prenant du recul par rapport à cette question spécifique, la bibliothèque des flux de Java 8 fournit toMap y groupingBy Collectionneurs . Si vous fusionnez de façon répétée des cartes dans une boucle, vous pouvez peut-être restructurer votre calcul pour utiliser des flux, ce qui peut à la fois clarifier votre code et permettre un parallélisme facile en utilisant un flux parallèle et un collecteur concurrent.

34voto

Xaerxess Points 10324

Si vous n'avez pas besoin de la mutabilité pour votre carte finale, il y a Goyave ImmutableMap avec son Builder y putAll méthode qui, contrairement à Java Map méthode d'interface peuvent être enchaînés.

Exemple d'utilisation :

Map<String, Integer> mergeMyTwoMaps(Map<String, Integer> map1, Map<String, Integer> map2) {
  return ImmutableMap.<String, Integer>builder()
      .putAll(map1)
      .putAll(map2)
      .build();
}

Bien sûr, cette méthode peut être plus générique, utiliser des varargues et boucler pour putAll Maps d'arguments etc. mais je voulais montrer un concept.

También, ImmutableMap et son Builder ont peu de limitations (ou peut-être de fonctionnalités ?) :

  • ils sont hostiles et nuls (lancer NullPointerException - si une clé ou une valeur de la carte est nulle)
  • Builder n'accepte pas les clés dupliquées (throws IllegalArgumentException si des clés en double ont été ajoutées).

27voto

hvgotcodes Points 55375

0 votes

Quel est le temps d'exécution de cette commande ? la doc ne semble pas le préciser. Je suppose que Theta(N) ?

21voto

fastcodejava Points 22174

Vous pourriez utiliser Collection.addAll() pour les autres types, par exemple List , Set etc. Pour Map vous pouvez utiliser putAll .

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