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

  1. #1
    Responsable Java

    Tutoriel pour développer un Switch/Case en programmation fonctionnelle avec Java 8
    Bonjour,

    François-Xavier Robin nous propose une façon d'écrire en Java 8 le switch/case en programmation fonctionnelle en s’appuyant sur des lambdas.

    Pour consulter le tutoriel : https://fxrobin.developpez.com/tutor...fonctionnelle/

    N'hésitez pas à laisser des commentaires à la suite.

    Mickael BARON pour l'équipe Java de Developpez.com

    Retrouvez les meilleurs cours et tutoriels pour apprendre le développement avec le langage Java
    Responsable Java de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Java, consulter la page cours
    N'hésitez pas à consulter la FAQ Java et à poser vos questions sur les forums d'entraide Java
    --------
    Ingénieur de Recherche en informatique au LIAS / ISAE-ENSMA
    Page de Developpez.com : mbaron.developpez.com
    Twitter : www.twitter.com/mickaelbaron
    Blog : mickael-baron.fr
    LinkedIn : www.linkedin.com/in/mickaelbaron
    DBLP : dblp.uni-trier.de/pers/hd/b/Baron:Micka=euml=l

  2. #2
    Membre expert
    Bien que je développe plus en Java depuis de nombreuses années, je trouve ton implémentation intéressante et très instructive....
    ...

  3. #3
    Membre éprouvé
    Très bel exercice intellectuel.
    Il y a des jours où j'éprouve une haine profonde envers microsoft
    Venez vous défouler ici ou c'est amusant
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  4. #4
    Membre expérimenté
    A la fois intéressant et utile. Un problème récurrent que j'ai eu avec la programmation fonctionnelle en Java est qu'elle devient illisible quand la logique implique des branchements complexes, voilà une bonne solution.

    Je modifierai SwitchExpression pour qu'elle étende Function. On pourrait ainsi s'en servir facilement avec Stream.map. Par exemple
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    List<String> reports = codes.stream()
        .map(
            Switch.defaultCase(code -> "Unknwown code " + code)
                .single(0, code -> "Success")
                // ...
                .build())
        .collect(Collectors.toList());

  5. #5
    Membre chevronné
    Bonjour, et merci à vous tous pour vos retours positifs, ça fait plaisir.

    Citation Envoyé par BugFactory Voir le message

    Je modifierai SwitchExpression pour qu'elle étende Function. On pourrait ainsi s'en servir facilement avec Stream.map. Par exemple
    Merci pour cette idée, que je vais prendre en compte immédiatement.

    Disons que l'interface SwitchExpression était là aussi pour illustrer la pratique des différentes étapes (et états) quand on fait du method-chaining.

    Voici les modifs apportées (visibles sur GitHub, pas dans l'article):

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public interface SwitchExpression <T, R> extends Function<T, R>
    {
       // unchanged
    }


    implémentation dans la classe Switch :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    @Override
    public R apply(T value)
    {
       return resolve(value);
    }


    et le test de son bon fonctionnement, ce qui a été le plus long à écrire ;-)

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    @Test
    public void StreamMapTest()
    {
            // switcher could have been written in the map method of the Stream.of(), 
            // but it's defined here for readability only.
            SwitchExpression<Integer, String> switcher = Switch.<Integer, String> start()
                                                               .defaultCase(v -> "ODD")
                                                               .predicate(v -> v % 2 == 0, v -> "EVEN")
                                                               .build();
     
            // just to check thats everything is fine
            assertNotNull(switcher, "cannot build the switcher");
     
            // let's run the Stream.map which will call the switcher.
            // the switcher implements Function <R, T> and its apply(T t) method.
            List<String> result = Stream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
                                        .map(switcher)
                                        .collect(Collectors.toList());
     
            // few tests on the list
            assertNotNull(result, "the returned list is null, which is unacceptable!");
            assertEquals(10, result.size(), "the returned list size is wrong, which is totally unacceptable!");
     
            // then lets count the EVEN and the ODD to verify the switcher behavior inside a Stream.map().
     
            Map<String, Long> statistics = result.stream().collect(Collectors.groupingBy(String::toString, Collectors.counting()));
     
            assertNotNull(statistics, "the returned map is null, which is unbelievable!");
            assertEquals(5L, statistics.get("ODD").longValue());
            assertEquals(5L, statistics.get("EVEN").longValue());
     
            // it's working!
    }



    Je ferai une mise à jour de mon article sur mon blog directement :
    https://www.fxjavadevblog.fr/functional-switch/


    Merci encore pour cette belle idée !

    F.X.
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...