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 :

Java 8 lambda, une égalité d'Integer ne fonctionne pas


Sujet :

Java

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 60
    Points : 44
    Points
    44
    Par défaut Java 8 lambda, une égalité d'Integer ne fonctionne pas
    Bonjour,

    J'ai un souci d'égalité d'Integer dans une expression lambda qui ne fonctionne pas et je ne comprend pas pourquoi, pourriez vous m'aidez ?

    D'abord j'ai ce code complètement fonctionnel :

    Type :
    this.intervention = un objet Intervention
    this.getInterventions() = une liste d'Intervention
    i.getIdIntervention() = l'Id de l'intervention (Integer)
    this.navigationBean.getIdIntervention() = retourne l'Id de l'intervention de l'url (Integer)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.intervention = this.getInterventions().stream().filter(i -> i.getIdIntervention().equals(this.navigationBean.getIdIntervention())).findFirst().get();
    Ce code fonctionne parfaitement le lambda me renvoie bien une Intervention, pas de souci, c'est la suite qui se complique :

    Je fait la même chose pour un Objectif :

    Type :
    this.objectif = un objet Objectif
    this.intervention.getObjectifs() = liste d'Objectif dans l'Intervention
    i.getIdTache() = l'id de l'Objectif (Integer) (Objectif hérite de Tache)
    this.navigationBean.getIdObjectif() = l'Id de l'objectif dans l'url (Integer)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.objectif = this.intervention.getObjectifs().stream().filter(i -> i.getIdTache().equals(this.navigationBean.getIdObjectif())).findFirst().get();
    Et cette fois ça ne marche pas, il me dit que qu'il ne trouve pas d'objet correspondant alors que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(Objectif o : this.intervention.getObjectifs()){
              if(o.getIdTache().equals(this.navigationBean.getIdObjectif())){
                      this.objectif = o;
                  }
    }
    Fonctionne parfaitement !

    Si vous avez une idée je suis preneur, je ne comprend vraiment pas ....

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Que donne


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    this.objectif = this.intervention.getObjectifs().stream().filter(i -> {
                      System.out.println(
                          i.getIdTache()+" = "+this.navigationBean.getIdObjectif()+"?"+
                          i.getIdTache().equals(this.navigationBean.getIdObjectif())
                          );
                      i.getIdTache().equals(this.navigationBean.getIdObjectif())
          }).findFirst().get();

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Il aime pas le System.out.println au milieu et je vois pas comment corriger l'erreur

    J'ai essayer en convertissant automatiquement (via netbean) le foreach en Functional Operation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    this.intervention.getObjectifs().stream().filter((o) -> (o.getIdTache().equals(this.navigationBean.getIdObjectif()))).forEach((o) -> {
                    this.objectif = o;
                });
    Ça ne marche pas, à mon avis il y a un bug dans les lambda c'est pas possible ....

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    J'ai juste oublié le return dans le code que je t'ai donné

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    this.objectif = this.intervention.getObjectifs().stream().filter(i -> {
                      System.out.println(
                          i.getIdTache()+" = "+this.navigationBean.getIdObjectif()+"?"+
                          i.getIdTache().equals(this.navigationBean.getIdObjectif())
                          );
                      return i.getIdTache().equals(this.navigationBean.getIdObjectif());
          }).findFirst().get();

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    ok dsl je débute avec les lambda

    Du coup j'ai essayer ton code, il a rien le temps de m'afficher il me met toujours la même erreur :

    WARNING: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
    java.util.NoSuchElementException: No value present

    J'ai passé le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.objectif = this.intervention.getObjectifs().stream().filter(i -> i.getIdTache().equals(this.navigationBean.getIdObjectif())).findFirst().get();
    en DEBUG et j'ai mis this.navigationBean.getIdObjectif() dans une variable x pour vérifier la valeur
    => this.intervention.getObjectifs() contient un seul élément de type Objectif ou idTache = 11562
    => x = 11562

    Franchement c'est incompréhensible cette histoire ...

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Le system.out.println est dans la console de ton serveur. Si la lambda n'affiche rien dans la console, c'est que ta liste est vide. A mon avis, en debug, tu ne regarde pas les mêmes objet que ceux que tu utilise dans ta lambda.
    Tu peux aussi afficher ça avant la lambda si tu veux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("Objectfis: "+this.intervention.getObjectifs());
    Je ne sais pas quel "x" tu regarde en debug, mais il n'y a pas de X dans ta lambda.

  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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    C'est quoi le type de this.intervention.getObjectifs() ?

    Et comme ça aussi, ça t'affiches l'exception avant autre chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    this.intervention.getObjectifs().stream()
    		.peek(i-> 
    				System.out.println(
    	                      i.getIdTache()+" = "+this.navigationBean.getIdObjectif()+"?"+
    	                      i.getIdTache().equals(this.navigationBean.getIdObjectif())
    	                      )
    		)
    		.filter(i -> i.getIdTache().equals(this.navigationBean.getIdObjectif())).findFirst().get();
    Fais aussi un essai en décomposant en plusieurs instructions, pour voir où se situe l'exception (à priori c'est sur le get(), mais c'est pour être sûr).

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    tchize_ :
    En fait j'ai fait sa :

    Integer x = this.navigationBean.getIdObjectif();
    this.objectif = this.intervention.getObjectifs().stream().filter(i -> i.getIdTache().equals(x)).findFirst().get();

    x = 11562
    this.intervention.getObjectifs().get(0).getIdTache() = 11562

    Pourtant je me prend une erreur.

    joel.drigo :
    J'ai essayer ton code, même problème, affichage de l'erreur uniquement

    Et oui c'est au niveau du get() ou du findFirst() car en réalité "this.intervention.getObjectifs().stream().filter(i -> i.getIdTache().equals(this.navigationBean.getIdObjectif()))" renvoie une liste ne contenant rien

    Pour moi c'est un problème dans le lambda car le foreach marche mais bon ...

  9. #9
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Tu fais le forEach exactement avec le même "x" (même type, même valeur) et la même instance de liste ?

    Parce que si le peek() n'affiche rien, je rejoins l'avis de @Tchize_ : le stream est vide, avant même l'application du filtre.

    Un System.out.prinln( this.intervention.getObjectifs().stream().count() ) dit quoi ?


    Je ne vois pas trop quel problème il pourrait y avoir dans le lambda...

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Bon, merci à vous deux je viens de trouver pourquoi

    En fait c'est le mode debug qui m'a trompé, je m'explique :

    Le bug est du soit à JPA soit au traitement que fait la lambda, de base les listes d'objets sont chargé en mode LAZY par JPA c'est à dire uniquement à la demande, c'est pour ça que je voyais bien mon objectif dans la liste en debug, par contre je viens de m’apercevoir que la lambda ne la charge pas , du coup j'ai passé la liste d'Objectif en EAGER dans l'objet Intervention, et ça fonctionne.

    Voila voila ...

  11. #11
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    J'y connais rien en JPA, et de comment fonctionne le mode LAZY, mais à priori, je dirais que c'est iterator() qui doit charger la liste, alors que splitIterator() ne doit pas le faire. Du coup ça marche avec un foreach et pas un stream. tu pourrais le vérifier en appelant .iterator() sur getObjectifs() juste avant l'appel de stream(). En tout cas, ce n'est pas le lambda.

    [EDIT] pour info : https://bugs.eclipse.org/bugs/show_bug.cgi?id=433075

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

Discussions similaires

  1. Une instruction simple qui ne fonctionne pas
    Par Claude_Azoulai dans le forum VB.NET
    Réponses: 3
    Dernier message: 14/02/2010, 17h08
  2. une fct modification qui ne fonctionne pas !
    Par hindou90 dans le forum C
    Réponses: 2
    Dernier message: 07/02/2010, 01h18
  3. Ajouter une référence de service ne fonctionne pas
    Par hbib85 dans le forum Windows Communication Foundation
    Réponses: 5
    Dernier message: 19/02/2009, 17h02
  4. une boucle for qui ne fonctionne pas
    Par piffeo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 06/11/2008, 21h52
  5. un count sur une jointure et ca ne fonctionne pas
    Par elbronziero dans le forum Langage SQL
    Réponses: 2
    Dernier message: 14/10/2004, 11h23

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