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

avec Java Discussion :

Compréhension de code


Sujet :

avec Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut Compréhension de code
    Bonjour,
    J'aimerais comprendre ce code qui calcule un hashCode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public int hashCode()   
           { 
               // On choisit les deux nombres impairs 
               int resultat = 7; 
               final int multiplier = 17; 
        
               // Pour chaque attribut, on calcule le hashcode 
               // que l’on ajoute au résultat après l’avoir multiplié 
               // par le nombre "multiplieur" : 
               resultat = multiplier*resultat + (nom==null ? 0 :
               nom.hashCode());
    Je voudrais savoir ce que veut dire ce que j'ai mise en gras
    Si quelqu'un a la réponse Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Je ne vois pas sur quoi tu bloques ... mais ce sont des choses triviales.

    le nom==null est un test pour savoir si la variable nom est initialisée/ pointe vers un objet valide. Ce test est obligatoire parce que tu vas appeler la méthode hashCode.

    Ou alors c'est sur le test ternaire (()?:). C'est un test qui est équivalent à un test classique sauf 1) qu'il est plus compact et donc on ne peut pas mettre plusieurs lignes de code 2) il produit un résultat - ici on peut mettre le test dans une opération ... ou autre cas classique le mettre à droite d'une affectation (<- hashcode = ((nom==null)? 0: nom.hashCode()).

    Donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        if (TEST) {
            CODE1
        } else {
            CODE2
        }
     
    // or
     
       ((TEST)? CODE1: CODE2)
    PS: parenthéser le test n'est pas forcément nécessaire

  3. #3
    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 : 55
    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,

    Citation Envoyé par foetus Voir le message
    PS: parenthéser le test n'est pas forcément nécessaire
    Attention : tout est dans le "forcément" !

    En l'occurrence, ici, à cause de la précédence du + sur l'opérateur ternaire, c'est indispensable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String nom="x";
    System.out.println(10 + (nom==null ? 0 : 10)); // => donne 20
    System.out.println(10 + nom==null ? 0 : 10); // => donne 10
    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.

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Attention : tout est dans le "forcément" !

    En l'occurrence, ici, à cause de la précédence du + sur l'opérateur ternaire, c'est indispensable :
    Tu as raison de soulever ce point
    Mais moi je parlais de parenthéser juste le test du test (et éventuellement 1 ou les 2 expressions) pour des questions de lisibilité (quoique lorsqu'il y a trop de parenthèses ) ... mais ce n'est pas obligatoire.
    Mais parenthéser le test en entier ou pas effectivement peut avoir des interprétations différentes : ici on a un cas précis

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Salut,


    Attention : tout est dans le "forcément" !

    En l'occurrence, ici, à cause de la précédence du + sur l'opérateur ternaire, c'est indispensable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String nom="x";
    System.out.println(10 + (nom==null ? 0 : 10)); // => donne 20
    System.out.println(10 + nom==null ? 0 : 10); // => donne 10
    ****************************
    Merci pour ton aide, pourquoi la 2ème ligne donne 10 ?

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    Citation Envoyé par foetus Voir le message
    Je ne vois pas sur quoi tu bloques ... mais ce sont des choses triviales.

    le nom==null est un test pour savoir si la variable nom est initialisée/ pointe vers un objet valide. Ce test est obligatoire parce que tu vas appeler la méthode hashCode.

    Ou alors c'est sur le test ternaire (()?:). C'est un test qui est équivalent à un test classique sauf 1) qu'il est plus compact et donc on ne peut pas mettre plusieurs lignes de code 2) il produit un résultat - ici on peut mettre le test dans une opération ... ou autre cas classique le mettre à droite d'une affectation (<- hashcode = ((nom==null)? 0: nom.hashCode()).

    Donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        if (TEST) {
            CODE1
        } else {
            CODE2
        }
     
    // or
     
       ((TEST)? CODE1: CODE2)
    PS: parenthéser le test n'est pas forcément nécessaire
    ********************************
    Merci pour ton aide je vois maintenant OK

  7. #7
    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 : 55
    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
    Citation Envoyé par xeron33 Voir le message
    ****************************
    Merci pour ton aide, pourquoi la 2ème ligne donne 10 ?
    Je l'ai écrit : à cause de la précédence de l'opérateur + sur l'opérateur ternaire. La précédence va déterminer dans quel ordre Java évalue les calculs intermédiaires et comment ils vont être combinés pour obtenir le résultat final.

    • Selon le type d'opérateur, on fait toujours un calcul sur un nombre déterminé d'opérandes :
      1. opérateur unaire : un seule opérande (par exemple l'opérateur !)
      2. opérateur binaire : deux opérandes (par exemple l'opérateur +).
      3. opérateur ternaire : trois opérandes

      S'il y a plusieurs opérateurs dans une expression, plus d'opérandes que l'opérateur peut traiter, on fait des calculs intermédiaires, par association , comme si on introduisait des parenthèses pour regrouper des calculs qui sont évaluables par Java, pour revenir au nombre d'opérandes que l'opérateur peut traiter, quand c'est possible bien sûr. De la même manière, s'il y a plusieurs opérateurs différents.

      Par exemple, pour 5 + 1 + 3, on va faire une somme entre 2 opérandes, puis une somme entre cette somme intermédiaire et le troisième opérande. A cause de l'associativité, l'ordre des opérations intermédiaires compte, en particulier si les opérateurs sont différents, comme dans 5 + 1 * 3, par exemple.
    • Lorsqu'on écrit une expression avec plusieurs opérateurs le résultat tient compte de la précédence : on ne fait pas les opérations dans un ordre quelconque.
      La précédence et l'ordre des opérandes sont importants :
      • Mathématiquement, déjà, tous les opérateurs ne sont pas commutatifs ( x op y n'est pas égale à y op x )..
      • Le type des opérandes compte en Java
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
         
        int x = 5;
        int y = 2;
        int r = x / y; // 2
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        double x = 5;
        double y = 2;
        double r = x / y; // 2.5
      • L'associativité ou la non associativité est déterminante. En particulier si les types des opérandes sont différents. Surtout qu'un calcul entre deux opérandes de types différents va effectuer une conversion.
        Par exemple :
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        String s0 = "a" + 1 + 2; // a12 parce qu'on calcule d'abord "a" + 1 puis "a1" + 2
        String s1 = "a" + (1 + 2); // a3 parce qu'on calcule d'abord 1 + 2 puis "a" + 3


      Prenons l'expression : x op y op z. On peut faire le calcul
      • de cette manière : (x op y) op z
        1. d'abord r0 ← x op y
        2. puis r1 ← r0 op z
      • de cette manière : x op ( y op z )
        1. d'abord r0 ← y op z
        2. puis r1 ← x op r0



      1. lorsque l'opérateur est le même, l'ordre est de gauche à droite (si l'opérateur est mathématiquement commutatif ça ne compte pas, mais s'il ne l'est pas l'ordre a une importance)
        1. int i = 5 + 1 + 3; // i vaut 9.
          5 + 1 + 3 = 1 + 3 + 5 → 9
        2. Code : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          int x = 12;
          int y = 2;
          int z = 3;
          int r = x / y / z; // r vaut 2
          Si on contraint l'ordre par des parenthèses, le résultat sera différent selon la position de ces parenthèses :
          Code : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          int x = 12;
          int y = 3;
          int z = 2;
          int r = (x / y) / z; // r vaut 2, on fait 12 / 3, ce qui fait 4, puis 4 / 2, ce qui fait 2
          Code : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          int x = 12;
          int y = 3;
          int z = 2;
          int r = x / ( y / z); // r vaut 12, on fait 3 / 2, ce qui fait 1, puis 12 / 1, ce qui fait 12


      2. Lorsque l'opérateur est différent, la précédence intervient aussi :
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        System.out.println(12 + 3 * 2); // 18 : la précédence fait qu'on traite le * avant le +
        System.out.println(12 + (3 * 2)); // 12 + 6 → 18 
        System.out.println((12 + 3) * 2); // 15 * 2 → 30


    Donc pour résumer, quand Java traite System.out.println(10 + nom==null ? 0 : 10);, il considère que, + étant précédent à l'opérateur ternaire, il doit calculer le résultat du +, un opérateur binaire, donc un + entre les deux opérandes de part et d'autre du +, donc 10 et nom. 10+"x" donc "10x". Puis on évalue la condition, "10x" == null, qui vaut false, donc le résultat de l'évaluation par l'opérateur ternaire est la valeur après le :, donc 10. CQFD.

    Alors que dans l'autre cas, System.out.println(10 + (nom==null ? 0 : 10));, les parenthèses imposent qu'on évolue le résultat de l'opérateur ternaire en premier, qui donne 10, puisque nom n'est pas null, puis on calcule 10 + 10, donc ça fait 20.
    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.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 899
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Donc pour résumer, quand Java traite System.out.println(10 + nom==null ? 0 : 10);, il considère que, + étant précédent à l'opérateur ternaire, il doit calculer le résultat du +, un opérateur binaire, donc un + entre les deux opérandes de part et d'autre du +, donc 10 et nom. 10+"x" donc "10x". Puis on évalue la condition, "10x" == null, qui vaut false, donc le résultat de l'évaluation par l'opérateur ternaire est la valeur après le :, donc 10. CQFD.

    Alors que dans l'autre cas, System.out.println(10 + (nom==null ? 0 : 10));, les parenthèses imposent qu'on évolue le résultat de l'opérateur ternaire en premier, qui donne 10, puisque nom n'est pas null, puis on calcule 10 + 10, donc ça fait 20.
    **************************************************
    Ok maintenant je vois bien MErci encore pour toutes ces infos
    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. compréhension de code en asp
    Par bidule123456 dans le forum ASP
    Réponses: 1
    Dernier message: 21/08/2007, 11h12
  2. compréhension de code (passage à une autre page)
    Par kokokaine dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 04/05/2007, 11h02
  3. Réponses: 3
    Dernier message: 12/01/2007, 09h42
  4. [VB-Access]recset! Pb de compréhension de code
    Par sk8bcn dans le forum VBA Access
    Réponses: 5
    Dernier message: 15/12/2006, 15h26
  5. Compréhension du code
    Par Ivanelis dans le forum Assembleur
    Réponses: 3
    Dernier message: 12/06/2006, 12h08

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