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

Langage Java Discussion :

Parcourir un java.util.Properties avec une lambda et un forEach


Sujet :

Langage Java

  1. #1
    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 Parcourir un java.util.Properties avec une lambda et un forEach
    Bonjour,

    Je viens de faire le code suivant, pour parcourir un java.util.Properties avec une lambda et un forEach en gardant les String et sans devoir créer une nouvelle map :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            Properties props = new Properties();
            ((Hashtable<String, String>) ((Hashtable<?,?>) props))
                .forEach((key,value) -> 
                    earnedMonths.put(Period.parse(key),Period.parse(value))
                    );
    Quelqu'un aurait-il mieux ?

    La Hashtable contient d'office des paires <String, String> mais quelqu'un de chez SUN/Oracle a décidé que ça implémenterait Map<Object,Object>...

    Merci d'avance.

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Personnellement je ferais une variable temporaire de type Map<String, String> au lieu de juste mettre une parenthèse alambiquée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Properties props = new Properties();
    @SuppressWarnings({ "unchecked", "rawtypes" }) // Properties only contain Strings!!!
    Map<String, String> propStrings = (Map)props;
    propStrings.forEach((key,value) -> 
      earnedMonths.put(Period.parse(key),Period.parse(value)));
    J'aurais aussi pensé à juste faire des cast sur key et value, mais du coup la lambda est bien moins lisible :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Properties props = new Properties();
    props.forEach((key,value) -> 
      earnedMonths.put(Period.parse((String)key),Period.parse((String)value)));
    Fondamentalement, le problème est que la classe Properties obsolète n'a pas la fonctionnalité nécessaire pour écrire du code simple et clair. Ma solution personnelle serait autant que possible s'en passer ou la planquer derrière une méthode utilitaire qui la convertit en jolie Map<String, String>, et s'arranger pour le faire assez tôt pour que ce soit pas dans le code qui va la traiter.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    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
    C'est effectivement un peu plus lisible

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Et ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     properties.entrySet().stream()
                    .map(entry -> (Map.Entry<String, String>) (Object) entry)
                    .forEach(entry -> earnedMonths.put(Period.parse(entry.getKey()), Period.parse(entry.getValue())));
    EDIT - correction de bourde : remplacement de values() par entrySet() et donc du coup double cast pour éviter une erreur de impossible de caster Map.Entry<Object, Object> en Map.Entry<String, String>
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  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
    j'ai l'impression avec ta solution de mettre plus de temps à comprendre ce que fait le code qu'avec la première de thelvin

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Ah ?! Pourtant meme moi qui ait parfois du mal avec les streams, je la trouve plutôt claire et même pas du tout éloignée de la tienne du début en fait :
    props.forEach(BiConsumer<Object, Object>) revient a faire props.entrySet().forEach(Consumer<Map.Entry<Object, Object>>).

    La fonction map() sert a convertir un stream d'un certain type T en un stream d'un autre type R.
    Ici, on passe donc d'un Stream<Map.Entry<Object, Object>> Stream<Map.Entry<String, String>>

    Bon ceci dit je viens de me rendre compte que :
    1) j'avais mis values() au lieu de entrySet() -> welcome le ClassCastException a l'execution.
    2) j'avais pas teste un code qui donc ne fonctionnait pas.

    Donc j'ai corrige le code mais ça demande de toute manière de mettre un second cast car on ne peut pas caster de Map.Entry<Object, Object> Map.Entry<String, String>. Il faut donc caster Map.Entry<Object, Object> Object Map.Entry<String, String> et donc c'est a nouveau pas beau.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  7. #7
    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
    j'ai pas dit qu'elle était impossible à lire non plus. C'est juste qu'alors que le but est juste de parcourir les entrée, on retrouve un map dans la lambda, ce qui amène à un temps de pause pour ce dire "ha tiens, on convertis les données?"

    j'ai opté au final pour la version avec le typecasting vers string sur la fin, qui reste la plus propre.


    Mais pourquoi diable Properties n'implémente pas Map<String,String> b*** de zut

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

Discussions similaires

  1. java.utils.Properties avec Expression Language
    Par pilate dans le forum Collection et Stream
    Réponses: 16
    Dernier message: 24/01/2010, 21h48
  2. Réponses: 1
    Dernier message: 11/11/2007, 17h54
  3. [java.util.logging]Faire une pause dans le logging
    Par anthyme dans le forum Logging
    Réponses: 6
    Dernier message: 08/03/2006, 10h43
  4. [PROPERTIES] Bug dans java.util.Properties ?
    Par mathieu dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 28/04/2004, 15h11

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