JavaRush /Blog Java /Random-FR /Se débarrasser des boucles dans Java 8
KapChook
Niveau 19
Volga

Se débarrasser des boucles dans Java 8

Publié dans le groupe Random-FR
Le style fonctionnel introduit dans Java 8 est un excellent ajout au langage. Maintenant, Java n'est pas une pure POO, c'est maintenant un hybride de POO et de programmation fonctionnelle. Cela change la donne et nous devons changer notre cerveau POO pour absorber ces changements. Se débarrasser des boucles en Java 8 - 1Mais pourquoi devrions-nous accepter ces changements ? Pourquoi devrions-nous perdre du temps à essayer d'adopter un style fonctionnel alors que nous pouvons résoudre le problème en utilisant la POO pure ?
  • Le style fonctionnel introduit dans Java 8 nous aide à réduire l'écart entre la logique métier et le code. Cela nous permet de raconter l’histoire avec un flux naturel à un niveau supérieur. Au lieu de dire comment vous voulez le faire, vous pouvez dire ce que vous voulez faire.

  • Le code devient plus clair et concis.

  • Les fonctions d'ordre élevé nous permettent de :

    • Envoyer des fonctions à d'autres fonctions
    • Créer des fonctions à l'intérieur d'autres fonctions
    • Renvoie les fonctions d'autres fonctions

    C'est une grande victoire pour Java, où nous devons envoyer, créer et renvoyer des objets pour ce faire. Nous pourrons écrire du code plus fiable, plus ciblé et plus facile à réutiliser.

  • Grâce aux lambdas, nous pouvons faire des calculs paresseux. Lorsqu'une expression lambda est envoyée comme argument de méthode, le compilateur l'évaluera lorsqu'elle sera appelée dans la méthode. Ceci est différent des arguments de méthode normaux, qui sont évalués immédiatement.

  • Les Lambdas rendent l'écriture de tests unitaires amusante. Ils nous permettent de créer des tests légers, propres, de petite taille et rapides à écrire. Nous pouvons extraire le code testé à l'aide de lambdas. Cela nous permet de tester comment toutes sortes de scénarios affecteront le code.

  • De nouveaux modèles à apprendre.

  • Et beaucoup plus!

Mais assez d’eau, nous allons dans cet article faire le tour des solutions alternatives aux cycles traditionnels. Bien sûr, les cycles sont flexibles, mais cela a un prix. break, modifient radicalement le comportement de la boucle, nous obligeant à comprendre non seulement ce que le code essaie d'accomplir, continuemais returnégalement à comprendre comment fonctionne la boucle. Nous allons maintenant voir comment transformer les boucles en un code plus concis et plus lisible.

Que le codage commence !

Nous travaillerons avec des articles. Un article a un titre, un auteur et plusieurs balises.
private class Article {

    private final String title;
    private final String author;
    private final List<String> tags;

    private Article(String title, String author, List<String> tags) {
        this.title = title;
        this.author = author;
        this.tags = tags;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public List<String> getTags() {
        return tags;
    }
}
Chaque exemple contiendra une solution traditionnelle utilisant des boucles et une solution utilisant les nouvelles fonctionnalités de Java 8. Dans le premier exemple, nous souhaitons retrouver le premier article de la collection avec la balise « Java ». Jetons un coup d'œil à une solution utilisant une boucle.
public Article getFirstJavaArticle() {

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            return article;
        }
    }
    return null;
}
Résolvons maintenant le problème en utilisant les opérations de l'API Stream.
public Optional<Article> getFirstJavaArticle() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .findFirst();
    }
Plutôt cool, n'est-ce pas ? Nous utilisons d’abord l’opération filterpour trouver tous les articles avec la balise « Java », puis nous utilisons findFirst()pour obtenir la première occurrence. Étant donné que les flux sont paresseux et que le filtre renvoie un flux, cette approche ne traitera les éléments que jusqu'à ce qu'elle trouve la première correspondance. Passons maintenant à tous les articles étiquetés « Java » au lieu du premier seulement. D'abord la solution utilisant des boucles.
public List<Article> getAllJavaArticles() {

    List<Article> result = new ArrayList<>();

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            result.add(article);
        }
    }
    return result;
}
Solution utilisant des opérations de flux.
public List<Article> getAllJavaArticles() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .collect(Collectors.toList());
    }
Dans cet exemple, nous avons utilisé une opération collectpour raccourcir le flux résultant, plutôt que de déclarer une collection et d'ajouter explicitement les entrées correspondantes. Jusqu'ici, tout va bien. Il est temps de donner des exemples qui feront vraiment briller l'API Stream. Regroupons tous les articles par auteur. Comme d'habitude, on commence par le résoudre à l'aide de boucles :
public Map<String, List<Article>> groupByAuthor() {

    Map<String, List<Article>> result = new HashMap<>();

    for (Article article : articles) {
        if (result.containsKey(article.getAuthor())) {
            result.get(article.getAuthor()).add(article);
        } else {
            ArrayList<Article> articles = new ArrayList<>();
            articles.add(article);
            result.put(article.getAuthor(), articles);
        }
    }
    return result;
}
Pouvons-nous trouver une solution propre à ce problème en utilisant des opérations de flux ?
public Map<String, List<Article>> groupByAuthor() {
    return articles.stream()
        .collect(Collectors.groupingBy(Article::getAuthor));
}
Incroyable! En utilisant une opération groupingByet une référence de méthode getAuthor(), nous obtenons un code propre et lisible. Trouvons maintenant le reste des balises utilisées dans la collection. Commençons par un exemple de boucle :
public Set<String> getDistinctTags() {

    Set<String> result = new HashSet<>();

    for (Article article : articles) {
        result.addAll(article.getTags());
    }
    return result;
}
Ok, voyons comment nous pouvons résoudre ce problème à l'aide d'opérations de flux :
public Set<String> getDistinctTags() {
    return articles.stream()
        .flatMap(article -> article.getTags().stream())
        .collect(Collectors.toSet());
}
Cool! flatmapnous aide à aplatir la liste des balises en un seul flux de résultats, que nous utilisons ensuite collectpour créer l'ensemble de retour.

Des possibilités infinies

Ce sont 4 exemples de la façon dont les boucles peuvent être remplacées par du code plus lisible. Assurez-vous de consulter l’API Stream, car cet article n’a fait qu’effleurer la surface. Maîtriser le nouveau style fonctionnel de Java sera un défi pour les développeurs POO, mais c'est un défi qui devrait être bien accueilli. J'irai même jusqu'à dire qu'il faut apprendre un langage de programmation purement fonctionnel. De cette façon, vous pouvez pleinement comprendre les capacités et la puissance qu’il fournit. Je pense que cela vous aidera à comprendre la programmation fonctionnelle à un autre niveau. Alors apprenez la programmation fonctionnelle avec la bonne vieille POO et utilisez-les toutes les deux pour écrire du code encore plus performant ! Un mélange gratuit de traductions de deux articles - Pourquoi vous devriez adopter la programmation fonctionnelle dans Java 8 et S'éloigner des boucles dans Java 8
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION