IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Problème pour comparer l'égalité de deux objets


Sujet :

Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Par défaut Problème pour comparer l'égalité de deux objets
    Bonjour,

    je vous soumets mon problème:

    Dans une application, je dois comparer l'égalité de deux instances d'un objet "Enregistrement" assez compliqué (beaucoup d'attributs).
    Pour cela je pourrais redéfinir et utiliser la méthode equals de cet objet!

    Mon problème est que la méthode equals a déjà été redéfini (il y a longtemps) pour ne comparer que peu de champs (les champs "id" et "version" correspondant à la clé primaire coté base de donnée), de sorte que dans l'application deux instances d'"Enregistrement" sont égales seulement si elles ont le même couple "id", "version"...

    Cette comparaison (qui est utilisée et suffit dans tout le reste de l'application) ne me va pas car j'ai besoin de comparer tous les autres attributs de l'objet "Enregistrement".

    Pour le moment, j'ai codé une méthode d'environs 400 lignes (beaucoup d'attributs) basée sur le equals standard que me générerais mon IDE. Cette méthode fait le travail... mais je la trouve vraiment horrible, et je doute que ma démarche constitue une bonne pratique

    Auriez-vous des idées pour remédier à ce problème?

    Bon week-end,
    Nicolas

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Il n'y a pas de miracle, si tu dois comparer tous les attributs, il faut le faire, donc si tu as beaucoup d'attributs, il y aura beaucoup de code. La méthode equals() déjà existante est effectivement suffisante (il ne peut y avoir 2 enregistrements de même clef primaire). Tu peux faire une autre méthode, par exemple isSameAs(), pour faire une comparaison sur les attributs, pour faire du dédoublonage par exemple.

    Ensuite, il faudrait voir précisemment comment la classe est faite : si les attributs sont des variables membres (en tout logique, si ce sont des attributs), tu est obligé de tous les comparer. Mais peut-être est-ce une classe qui stocke des propriétés dans une map (avec un getter et un setter par propriété), auquel cas, une boucle sur l'entrySet permettra de réduire le code. Dans le cas d'attributs, on peut procéder éventuellement de manière similaire (boucle) par réflexion (avec perte de performance).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Par défaut
    Salut, c'est bien ce qui me semble, il n'y a pas de miracle. Je n'ai pas de stockage de dans des map dans cette classe, le seul problème est qu'il y a beaucoup d'attributs.

    La méthode equals existante est suffisante dans le reste de l'application. En ce qui me concerne je dois implémenter la fonctionnalité de pouvoir modifier un "enregistrement" existant.
    - Si l'utilisateur a fait des modifications et valide : enregistrer ces modifications (création nouvelle version etc...).
    - Si l'utilisateur n'a fait aucune modification et valide: ne rien faire (ne pas créer de nouvelle version!)

    Dans ce cas il faut que je compare les attributs de mon enregistrement de référence et de sa "working copy" et le equals implementé ne me suffit pas.

    Merci de m'avoir répondu si vite.

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Dans la mesure où ce test d'égalité intervient dans un test ponctuel, on peut accepter une légère perte de performance dans la comparaison. Dans ce cas, je le ferait par réflexion dans une méthode qui teste s'il y a une modification, plutôt que de tester l'égalité.

    Pour la réflexion, soit tu boucles sur les attributs, soit tu boucles sur un tableau d'attributs. Si tous les attributs, ou s'il y a un moyen de reconnaitre (rapidement) un attribut (une particularité dans le nom, par exemple), on peut boucler sur les attributs. Sinon, même si c'est fastifieux de créer le tableau d'attributs au début (il y a éventuellement une possibilité de le faire dynamiquement), parcourir le tableau et retrouver l'attribut par getField() sera plus simple. On stocker aussi les attributs dans Set, et l'utiliser comme filtre pour boucler sur tous les attributs qu'on veut comparer.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Par défaut
    Merci beaucoup,

    Je vais essayer dans cette voie. J'ai fait quelques essaies qui ne sont pas tout à fait encore concluants:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public boolean isSameAs(MaClasse maClasse) {
    		Class<? extends MaClasse> thisClasse = this.getClass();
    		Class<? extends MaClasse> classeTestee = maClasse.getClass();
     
    		Field[] attributs = thisClasse.getDeclaredFields();
     
    		for (Field attribut : attributs) {
    			try {
    				if (!isSameAttribut(thisClasse, classeTestee, attribut)) {
    					return false;
    				}
    			} catch (NoSuchFieldException | SecurityException e) {
    				e.printStackTrace();
    			}
    		}
    		return true;
    	}
     
    	private boolean isSameAttribut(Class<? extends MaClasse> thisClasse,
    			Class<? extends MaClasse> classeTestee, Field attribut)
    			throws NoSuchFieldException {
    		return thisClasse.getDeclaredField(attribut.getName()).equals(
    				classeTestee.getDeclaredField(attribut.getName()));
    	}
    Il y a quelques problèmes et je n'ai pas vraiment les résultats attendus mais c'est une question de temps pour que ce code marche (avec des attributs public). Si les attributs sont privées, je pense que ce sera plus compliqué mais je pourrais peut-être m'en sortir avec la méthode ".setAccessible(true)"

    En tout cas merci pour votre aide, je vais creuser dans cette voie.

  6. #6
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Citation Envoyé par nico783 Voir le message
    En ce qui me concerne je dois implémenter la fonctionnalité de pouvoir modifier un "enregistrement" existant.
    - Si l'utilisateur a fait des modifications et valide : enregistrer ces modifications (création nouvelle version etc...).
    - Si l'utilisateur n'a fait aucune modification et valide: ne rien faire (ne pas créer de nouvelle version!)
    Je déconseille la réflexivité pour ce genre de choses : tu peux faire en sorte que ça marche dans ton cas précis, mais tu risques de masquer d'autres problèmes.
    Ne joue pas non plus avec les paramètres d'accessibilité : si ta classe a des attributs privée, ils ne doivent pas être visibles.

    Du coup, je te propose une autre solution : implémente un état dans ta classe Enregistrement, état qui passe à True dès que l'un des champs est modifié. De cette façon, tu n'as pas à vérifier tous les champs, il suffit qu'un seul soit modifié pour que tu saches que tu dois provoquer l'enregistrement.

  7. #7
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Août 2014
    Messages : 262
    Par défaut
    Citation Envoyé par eulbobo Voir le message
    Du coup, je te propose une autre solution : implémente un état dans ta classe Enregistrement, état qui passe à True dès que l'un des champs est modifié. De cette façon, tu n'as pas à vérifier tous les champs, il suffit qu'un seul soit modifié pour que tu saches que tu dois provoquer l'enregistrement.
    Je préfère plutôt sa méthode. Mais du coup on ne sait pas quel attribut a été modifié ! Plus optimisé serait de n'enregistrer que les attributs qui ont été modifiés. Je n'ai pas réfléchit à comment le faire mais je pense que ce serait pas trop demander !

Discussions similaires

  1. Réponses: 7
    Dernier message: 14/12/2014, 20h09
  2. [EF][C#] Problème pour mapper 2 tables vers 1 objet
    Par badack dans le forum Accès aux données
    Réponses: 5
    Dernier message: 19/12/2008, 09h41
  3. Problème pour comparer deux mots
    Par Fredo123456 dans le forum C
    Réponses: 4
    Dernier message: 18/02/2008, 23h25
  4. Problème pour Comparer 2 Datatables et mise à jour
    Par Jean-Marc68 dans le forum C#
    Réponses: 4
    Dernier message: 21/11/2007, 20h28
  5. Problème pour comparer 2 horaires
    Par jerome71300 dans le forum C#
    Réponses: 5
    Dernier message: 10/11/2007, 13h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo