Pour le cadre d'un projet, je dois comparer 2 HashMap et stocker les différences.
MAP1 <String, Objet>
MAP2 <String, Objet>
J'ai des gros flux à comparer, je me pose des questions au niveau de la complexité. Dans un premier temps je comptais faire ça :
for (String cle: MAP1.keySet()){
for (String cle2: MAP2.keySet()){
if(cle.equals(cle2){
if(MAP1.equals(MAP2)
return true
else
return false
}
}
}
Je prend la 1ere clé de MAP1, je la cherche dans MAP2 si elle y est, je compare le contenu de mes objets.
Est-ce le meilleur moyen de faire ça ?
Merci d'avance
Clairement, non, ce n'est pas le meilleur moyen !
Quand on a une clé (prise dans MAP1), on ne fait pas une boucle pour la chercher dans MAP2. On interroge MAP2, par exemple avec containsKey
for (String cle: MAP1.keySet()){
if (MAP2.containsKey(cle)) {
....
}
}
Le parcours d'une Map coûte cher (temps proportionnel au nombre d'éléments qu'elle contient), alors que containsKey donne un accès direct (en temps amorti moyen constant, excusez le pédantisme).
Ensuite, il faudrait mieux préciser à quoi ça sert, parce que je ne suis pas sur qu'un parcours par des boucles soit la bonne solution à tous les problèmes.
Il y a plus simple : on récupère les clés d'une des maps, on enlève les clés qui ne sont pas dans l'autre, et voila. Il y a des opérations sur les collections, il faut en profiter.
// copie de la collection des clés du premier
var Set<String> cles = new HashSet<>(MAP1.keySet());
// on ne conserve que les clés qui sont dans le second
cles.retainAll(MAP2.keySet());
// et voila
clés contient les clés communes aux deux ensembles (l'intersection).
Techniquement, ça va faire tomber la complexité de n1 x n2 à n1.log(n1) + n2.log(n2) , en fonction des tailles n1 et n2 des maps.
J'ai cru comprendre que les keyset des 2 maps étaient identiques et que les différences étaient uniquement au niveau des objets associés, ce n'est pas le cas?
Et bien il a des clés qui permettent de chercher des personnes dans deux maps. On va supposer que ces clés servent à identifier les personnes. Les maps donnent des infos.
Et il veut voir quelles infos diffèrent d'une map à l'autre, entre les objets qui sont censés contenir à peu près les mêmes infos. Ce qui a changé.
Quand on a une clé (prise dans MAP1), on ne fait pas une boucle pour la chercher dans MAP2. On interroge MAP2, par exemple avec containsKey
for (String cle: MAP1.keySet()){
if (MAP2.containsKey(cle)) {
....
}
}
Le parcours d'une Map coûte cher (temps proportionnel au nombre d'éléments qu'elle contient), alors que containsKey donne un accès direct (en temps amorti moyen constant, excusez le pédantisme).
- Edité par michelbillaud il y a environ 17 heures
Je pense que je vais avoir besoin de cette solution !
Play50hz a écrit:
J'ai cru comprendre que les keyset des 2 maps étaient identiques et que les différences étaient uniquement au niveau des objets associés, ce n'est pas le cas?
Effectivement, théoriquement je suis censé avoir le même nombre d'éléments dans mes 2 maps, et que les keyset des 2 maps sont identiques et que les différences sont uniquement sur l'objet associés.
Et mon but est d'afficher les keyset où il y a une différence au niveau des objets (Je ne sais pas si j'ai été clair)
Dans ce cas, n'ayant pas l'assurance que l'ordre naturel est préservé dans les collections values si tu fais un sort, le plus simple je pense est d'itérer sur les clé d'une des map, sortir les values des 2 maps, et les comparer.
Tu peux faire ça avec un stream, un filtre et un collect pour sortir facilement une liste de ce qui n'est pas equals
Bon donc on est bien dans le cas ou les deux maps ont LE MEME ensemble de clés ?
Comme on a besoin de chaque clé ET de l'objet qui va de la map1 pour comparer l'objet avec son copain de la map2, je ferais plutot un stream sur l' entrySet, pour avoir les deux d'un coup
var messages =
map.entrySet().stream()
.map( entry -> traficoter(entry.key(), entry.value(), map2.get(entry.key())) // produit des messages ?
.collect(....);
Bon donc on est bien dans le cas ou les deux maps ont LE MEME ensemble de clés ?
Comme on a besoin de chaque clé ET de l'objet qui va de la map1 pour comparer l'objet avec son copain de la map2, je ferais plutot un stream sur l' entrySet, pour avoir les deux d'un coup
var messages =
map.entrySet().stream()
.map( entry -> traficoter(entry.key(), entry.value(), map2.get(entry.key())) // produit des messages ?
.collect(....);
Oui c'est ça !
Donc la solution la plus efficace c'est partir sur un stream et non pas sur mes boucles for !
Je vais essayer de me renseigner sur les streams et faire des tests ! Merci à vous
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl
PXL Le retro gaming facile Thread sur le forum: https://openclassrooms.com/forum/sujet/retro-pxl