Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > ETL > Talend
Talend Forum d'entraide sur Talend (Talend Open Studio, ...). Avant de poster --> FAQ Talend, Tutoriels Talend
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/02/2011, 12h57   #1
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Par défaut Egalité entre 2 entiers

Bonjour,

Un mini débat a été soulevé par un de mes collègues sur la bonne façon de gérer les égalités entre les entiers dans Talend.

N'ayant pas de verni java, j'ai l'habitude d'utiliser le == entre 2 entiers, que ce soit des variables ou des données en dur.

Lors d'une revue de code, je tombe sur un .equals utilisé sur un champ défini en entier. Suite à la discussion que j'ai eu avec la personne qui avait codé ça, je comprends que c'est une bonne pratique java qui impose d'utiliser le .equals (car un == entre 2 Integer en java ne fonctionne pas, il me l'a démontré avec un petit test en java pur).

J'ai fait quelques tests avec Talend, et je n'ai pas identifié de soucis avec le ==, même entre 2 Integer (je ne suis pas capable d'analyser comment Talend gère ça dans le code qui génère, du coup je ne sais pas dire si c'est fiable ou pas...).

Est-ce que quelqu'un a déjà réfléchi à ce point, et du coup argumenter pour l'une ou l'autre des solutions ?

Merci,
Nicolas
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2011, 17h56   #2
Membre extrêmement actif
 
Avatar de jojodu31
 
Inscription : mars 2008
Messages : 870
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2008
Messages : 870
Points : 733
Points : 733
Bonjour,
je présuppose (arrêtes moi si je me trompe) que quand tu as vérifié que tes tests avec == fonctionnaient tu n'avais pas 2 Integer mais peut être un Integer de l'autre coté et un int de l'autre.
Le equals() est à utiliser lorsque tu utilises le wrapper de int (qui est donc Integer et qui est un Object). == fonctionne pour le type primitif int. Si tu compare un Integer et un int, l'Integer est automatique transformé en son type primitif int (auto unboxing).

J'espère être clair
__________________
Heureux soient les fêlés, car ils laisseront passer la lumière.

Mieux vaut fermer sa gueule et passer pour un con que l'ouvrir et ne laisser aucun doute à ce sujet.
jojodu31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2011, 17h57   #3
Membre actif
 
Consultant informatique
Inscription : mars 2003
Messages : 130
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : mars 2003
Messages : 130
Points : 181
Points : 181
Tu as du remarquer losqu'on choisit le type d'un champ entier il y a noté "int | Integer" :
- int est un type primitif
- Integer est un object qui contient un champs int
pour le creer en java pur il faut :
Interger n =new Integer(4);
On ne peut pas utiliser le == sur les Integer car c'est un object mais heureusement la méthode equals compare 2 Integer et renvoie un boolean

Sur ton schéma de donnée en Entrée si la case nullable est coché Talend choisira d'utiliser le type Integer et non le type int car un type primitif ne peut pas être null
Si la case est décoché il va choisir int qui prend moins de place en mémoire donc plus efficace .

La raison de la bonne pratique est que == vérifie si les deux entrée sont les même object alors que la méthode equals vérifie elle si les deux entrées ont la même valeur.

Un peu plus d'info sur cet page :
http://leepoint.net/notes-java/data/...reobjects.html
kisskool45 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2011, 11h08   #4
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Citation:
Envoyé par jojodu31 Voir le message
Bonjour,
je présuppose (arrêtes moi si je me trompe) que quand tu as vérifié que tes tests avec == fonctionnaient tu n'avais pas 2 Integer mais peut être un Integer de l'autre coté et un int de l'autre.
Le equals() est à utiliser lorsque tu utilises le wrapper de int (qui est donc Integer et qui est un Object). == fonctionne pour le type primitif int. Si tu compare un Integer et un int, l'Integer est automatique transformé en son type primitif int (auto unboxing).

J'espère être clair
Ah non, j'ai bien testé tous les cas (int==int, int==Integer et Integer==Integer).
J'ai fait ça dans un tmap et les 3 fonctionnent.
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2011, 11h11   #5
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Citation:
Envoyé par kisskool45 Voir le message
Tu as du remarquer losqu'on choisit le type d'un champ entier il y a noté "int | Integer" :
- int est un type primitif
- Integer est un object qui contient un champs int
pour le creer en java pur il faut :
Interger n =new Integer(4);
On ne peut pas utiliser le == sur les Integer car c'est un object mais heureusement la méthode equals compare 2 Integer et renvoie un boolean

Sur ton schéma de donnée en Entrée si la case nullable est coché Talend choisira d'utiliser le type Integer et non le type int car un type primitif ne peut pas être null
Si la case est décoché il va choisir int qui prend moins de place en mémoire donc plus efficace .

La raison de la bonne pratique est que == vérifie si les deux entrée sont les même object alors que la méthode equals vérifie elle si les deux entrées ont la même valeur.

Un peu plus d'info sur cet page :
http://leepoint.net/notes-java/data/...reobjects.html
Oui, ok.
Mais je me pose toujours la question : est-ce que si je mets des == partout dans Talend je vais tomber sur des problèmes ou est-ce que le code qui est généré aujourd'hui fait que ça marche bien ?
(Parce que d'après ce que j'ai testé, ça marche...)

Ça m'embête un peu d'expliquer aux gens que je forme à Talend qu'il faut faire gaffe au fait que leur entier soit nullable ou pas, et que suivant le cas il faut utiliser l'un ou l'autre pour tester une égalité...
(Quand on a bossé sur d'autres ETL genre Datastage ou Informatica, ça semble un peu tordu...)

Nicolas
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2011, 11h26   #6
Membre actif
 
Consultant informatique
Inscription : mars 2003
Messages : 130
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : mars 2003
Messages : 130
Points : 181
Points : 181
== test toujours l'égalité des Objet cependant c'est facile de se faire avoir :

Code :
1
2
3
4
5
6
7
8
9
10
 
Integer a = 10;
Integer b = 10;
 
System.out.println(a == b); //TRUE
 
Integer c = new Integer(10);
Integer d = new Integer(10);
 
System.out.println(c == d); //FAUX
Quand on initialise l'objet a et b avec 10 on l'initialise avec une primitive 10
le même objet est utilisé pour a et b d'ou le == qui retourne vrai
Mais ce n'est pas la Valeur qui a été testé seulement a savoir si c t le même objet.

En regardant de plus près dans le code de Talend je me suis apercu que les variable Integer été lu sur l'InputStream grâce à la méthode readInt() qui renvoie un int (une primitive donc) .
voila pourquoi == entre Integer et Integer donne un resultat bon
Cependant, C'est une source d'erreur à éviter absolument !
kisskool45 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2011, 12h57   #7
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Ok, merci pour ces précisions.

Donc si j'ai bien compris, tu me confirmes qu'en utilisant systématiquement == avec Talend, je n'aurais pas de soucis. (Même si en java, il ne faut jamais le faire)

Et en fait, ça fonctionne sous Talend parce qu'ils utilisent systématiquement la méthode readInt() lors de l'utilisation des champs Integer.

J'ai bon ?
Nicolas
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2011, 14h21   #8
Membre actif
 
Consultant informatique
Inscription : mars 2003
Messages : 130
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Consultant informatique

Informations forums :
Inscription : mars 2003
Messages : 130
Points : 181
Points : 181
Je pense en effet que sur Talend ca ne posera jamais de problème.
Mais il faut rester vigilent quand même car je n'ai pas non plus regardé le fonctionnement de tous les composants Input.
kisskool45 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2011, 16h35   #9
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Ok, super.

Je vais partir là dessus.
Et je vais quand même essayer de me renseigner coté Talend pour voir s'ils peuvent me répondre là dessus.

Merci pour votre aide à tous les 2 !

Nicolas
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2011, 12h20   #10
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Bon, je reviens sur ce que j'ai dit.

Sur la suggestion d'un collègue, j'ai refait mon test en utilisant des valeurs plus grandes pour mes Integer, et le == ne fonctionne plus entre 2 Integer !
(Ce serait dû à l'utilisation d'un système de cache, qui n'est plus possible pour les grandes valeurs...)

Donc je vais partir sur les préconisations suivantes :
- Utiliser systématiquement le .equals pour tester l'égalité entre 2 valeurs, quel que soit le format.
- Sauf pour les égalités entre 2 int, pour lesquelles il faut utiliser le ==

Des remarques par rapport à ça ?
Nicolas
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2011, 13h40   #11
Membre extrêmement actif
 
Avatar de jojodu31
 
Inscription : mars 2008
Messages : 870
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2008
Messages : 870
Points : 733
Points : 733
Système de cache ? Ton test ne fonctionne déjà pas pour deux new Integer(3) ce n'est pourtant pas une grande valeur...
__________________
Heureux soient les fêlés, car ils laisseront passer la lumière.

Mieux vaut fermer sa gueule et passer pour un con que l'ouvrir et ne laisser aucun doute à ce sujet.
jojodu31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2011, 15h26   #12
Expert Confirmé
 
Avatar de Uther
 
Homme
Inscription : avril 2002
Messages : 2 297
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : avril 2002
Messages : 2 297
Points : 3 957
Points : 3 957
Le système de cache(je ne connais pas le nom exact) est utilisé lors de l'autoboxing (le système de conversion automatique de int en Integer). C'est ce qui explique le résultat suivant dans l'exemple de kisskool45
Citation:
Integer a = 10;
Integer b = 10;

System.out.println(a == b); //TRUE
Sur la ligne "Integer b = 10;" Au moment de convertir 10 en Integer, la JVM constate qu'il existe déjà un objet Integer contenant 10 et fait donc pointer b sur celui-ci.
a et b pointant vers le même objet a == b vaut vrai

Cependant ce système de cache est un mécanisme interne de la JVM (il y a système équivalent pour les String) et il ne faut faut surtout pas s'appuyer dessus : il ne fonctionne que dans certains cas comme l'autoboxing et seulement pour les nombres de -128 à 127.
Dans l'exemple de kisskool45 on voit bien que ça ne fonctionne plus avec des "new Integer()". De plus avec des nombres supérieurs à 127, ça ne fonctionnerait plus dans aucun cas.

Bref il ne faut jamais faire confiance au == pour des types non primitif. Parfois on peut avoir l'impression que ça marche mais ça risque de casser a tout moment.
Pour éviter les mauvaises surprises, il faut utiliser systématiquement .equals()
Uther est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/02/2011, 13h44   #13
Membre émérite
 
Homme Nicolas Saumande
Architecte Décisionnel
Inscription : février 2008
Messages : 693
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Saumande
Âge : 36
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Architecte Décisionnel

Informations forums :
Inscription : février 2008
Messages : 693
Points : 879
Points : 879
Merci pour toutes ces précisions !
DevNico est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h33.


 
 
 
 
Partenaires

Hébergement Web