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 :

le max et le min d'une liste: un code Java 8 donnant un résultat inattandu


Sujet :

Java

  1. #1
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2010
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 212
    Points : 184
    Points
    184
    Par défaut le max et le min d'une liste: un code Java 8 donnant un résultat inattandu
    voici le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    final List<Integer> list = new ArrayList<>();
            for (int i = 1; i <= 20; i++) {
                list.add(-i);
            }
     
            System.out.println("le max est: " + list.stream().max(Integer::max).get());
            // System.out.println("le max est: " +list.stream().max(Integer::compare).get());
            System.out.println("le min est: " + list.stream().min(Integer::min).get());
            // System.out.println("le min est: " +list.stream().min(Integer::compare).get());
    résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    le max est: -20
    le min est: -1
    Je n'arrive pas à interpréter ce résultat!!

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Parce que tu as créé un ObjectStream, que le Max prend en paramètre un comparator et que tu lui passe Integer::Max comme comparator, alors que ce n'est pas un Comparator.

    Soit tu travail avec Integer::max et un reduce:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list.stream().reduce(Integer::max)
    Soit tu travaille avec Stream.max et un comparator
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list.stream().max(Integer::compare)

  3. #3
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2010
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 212
    Points : 184
    Points
    184
    Par défaut
    Merci Beaucoup pour la réponse.
    j'aimerais avoir une explication, comment est ce que mon code a donné ces résultats. Je ne me demande pas pour quoi les résultats affichés ne sont pas correctes, Mais pour quoi un tel résultat (Max = -20? c'est très bizarre, pour quoi pas -19, ou -10,etc).

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Il n'y a pas de pourquoi.

    max() et min() exigent en paramètre un objet Comparator cohérent, c'est-à-dire que pour tout A, B et C, si A < B alors B > A ; et si A < B et B < C alors A < C.
    Si cette cohérence n'est pas respectée alors les résultats sont imprévisibles et n'ont aucun sens.

    Le paramètre que tu as donné n'est pas un Comparator cohérent. Les résultats n'ont donc aucun sens.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Le comparator a,b doit retourner une valeur < 0 si a <b , >0 si a>b ou ==0 a==b

    la méthode Integer::max retourne la valeur max. Donc toujours un nombre négatif dans ton cas, donc toujours a<b.
    La valeur que tu obtiens de ton stream au final est donc toujours la dernière de la liste du stream: a<b, b<c, c<d, ....
    La méthode Integer::min fait le même, donc a est choisi:a <b, a<c, a<d, ...

  6. #6
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2010
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 212
    Points : 184
    Points
    184
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Le comparator a,b doit retourner une valeur < 0 si a <b , >0 si a>b ou ==0 a==b

    la méthode Integer::max retourne la valeur max. Donc toujours un nombre négatif dans ton cas, donc toujours a<b.
    La valeur que tu obtiens de ton stream au final est donc toujours la dernière de la liste du stream: a<b, b<c, c<d, ....
    La méthode Integer::min fait le même, donc a est choisi:a <b, a<c, a<d, ...
    si j'ai bien compris:
    1. en cas max ((a, b) -> Integer.max(a,b)):

    (-1, -2) -> max (-1, -2) donne -1 et puisque c'est c'est un nombre négatif c'est -2(b) qui est choisi. on répète le même processus, on obtient au final -20. c'est tout a fait logique.
    1. en cas min ((a, b) -> Integer.min(a,b)):

    on applique le même raisonnement:
    (-1, -2) -> min (-1, -2) donne -2 et puisque c'est c'est un nombre négatif c'est -2(b) qui est choisi. on répète le même processus, on obtient au final -20 et pas -1??

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Bien sûr que non c'est pas -2 qui est choisi dans le cas min(), puisqu'on choisit le minimum -_-°.
    On choisit celui qui est censé être le plus petit, donc le premier, donc -1.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par win_ubuntu Voir le message
    on applique le même raisonnement:
    (-1, -2) -> min (-1, -2) donne -2 et puisque c'est c'est un nombre négatif c'est -2(b) qui est choisi. on répète le même processus, on obtient au final -20 et pas -1??
    donne -2 donc c'est négatif, donc -1 < -2 donc le min est -1, on répète on obtiens -1

  9. #9
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par win_ubuntu Voir le message
    si j'ai bien compris:
    1. en cas max ((a, b) -> Integer.max(a,b)):

    (-1, -2) -> max (-1, -2) donne -1 et puisque c'est c'est un nombre négatif c'est -2(b) qui est choisi. on répète le même processus, on obtient au final -20. c'est tout a fait logique.
    1. en cas min ((a, b) -> Integer.min(a,b)):

    on applique le même raisonnement:
    (-1, -2) -> min (-1, -2) donne -2 et puisque c'est c'est un nombre négatif c'est -2(b) qui est choisi. on répète le même processus, on obtient au final -20 et pas -1??
    Non. Comme te l'ont deja dit thelvin et tchize, le signe d'une fonction de comparaison permet de savoir si l'element 1 est inferieur, egal ou supérieur à l'element 2.
    Dans ta fonction de comparaison, tu utilises soit un min, soit un max. Et comme tous tes nombres sont negatifs, min/max renverra toujours un résultat negatif qui veut dire que l'element 1 est plus petit que le 2.

    Ensuite, dans ton 1er test, tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list.stream().max(Integer::max).get()
    Tu cherches donc le max (du stream, je ne parle pas de la fonction de comparaison).

    Et dans le 2eme test, tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list.stream().min(Integer::min).get()
    Tu cherches donc le min(du stream, je ne parle pas de la fonction de comparaison).

    Il est donc plutot cohérent de trouver le résultat opposé si tu cherches le min et le max. Note que comme on te l'a deja dit, comme ta fonction de comparaison ne respecte pas les regles d'une fonction de comparaison, le résultat n'est pas prévisible et depend fortement de l'implementation. Il n'est pas garanti que tu obtiennes le meme résultat. D'ailleurs, si tu remplis ta liste dans un autre ordre, tu trouveras toujours le 1et element comme min et le dernier comme max (encore une fois, parce que tu remplis ta liste avec des nombres négatifs).

    Note également que comme je l'ai dit, vu que tous tes elements sont negatifs, utiliser comme comparateur min ou max ne change rien.

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

Discussions similaires

  1. Créer une liste de codes
    Par hug33k dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 07/08/2011, 21h24
  2. [XL-2003] afficher une liste de code dans une msgbox
    Par will-1981 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 08/10/2010, 09h44
  3. défilement d'une liste par code
    Par subzero01 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 03/06/2008, 11h49
  4. Par quel moyen exécuter une liste de code SQL
    Par Bourezak dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 23/01/2008, 15h27
  5. chercher un max et min dans une liste de type vector
    Par sandy07 dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 29/05/2007, 15h23

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